diff --git a/Parser/spec/semantics/ExpressionHandling.jrag b/Parser/spec/semantics/ExpressionHandling.jrag new file mode 100644 index 0000000000000000000000000000000000000000..1222a6709c908199f3b810ebcc2f5f9891f639df --- /dev/null +++ b/Parser/spec/semantics/ExpressionHandling.jrag @@ -0,0 +1,18 @@ +aspect ExpressionHandling { + + syn boolean Expr.isPrimary(); + eq Expr.isPrimary() = false; + eq Primary.isPrimary() = true; + + syn Primary Expr.primary(); + eq Expr.primary() = null; + eq Primary.primary() = this; + + syn boolean Expr.isFunctionReference(); + eq Expr.isFunctionReference() = false; + eq FunctionReference.isFunctionReference() = true; + + syn FunctionReference Expr.functionReference(); + eq Expr.functionReference() = null; + eq FunctionReference.functionReference() = this; +} \ No newline at end of file diff --git a/Parser/spec/semantics/SlotTypes.jrag b/Parser/spec/semantics/SlotTypes.jrag new file mode 100644 index 0000000000000000000000000000000000000000..64a0804d1335ee5584ab736e840093511cb0c934 --- /dev/null +++ b/Parser/spec/semantics/SlotTypes.jrag @@ -0,0 +1,14 @@ +aspect SlotTypes { + + // =============================================================================================== + // Variable and Designator RESOLVING + // =============================================================================================== + + // syn ASTNode Variable.declaration(); + eq SlotVariable.declaration() = null; + + + // syn ASTNode Designator.declaration(); + eq SlotDesignator.declaration() = null; + +} \ No newline at end of file diff --git a/Parser/spec/semantics/Types.jrag b/Parser/spec/semantics/Types.jrag index ab95a14a4d001aa747bc659b32784350622050e8..17fa1be13f8688e741e7a47d4bf64ea68683a785 100644 --- a/Parser/spec/semantics/Types.jrag +++ b/Parser/spec/semantics/Types.jrag @@ -1,25 +1,223 @@ aspect Types { + // =============================================================================================== + // Variable and Designator RESOLVING + // =============================================================================================== + + syn ASTNode Variable.declaration(); + eq Designator_Variable.declaration() = getDesignator().declaration(); + eq Expr_Variable.declaration() { + + // C602 (R602) expr shall be a reference to a function that has a data pointer result. + + // if (getExpr().isPrimary()) { + // if (getExpr().primary().isFunctionReference()) { + // return getExpr().primary().functionReference().getProcedureDesignator().getDataRef().lookup(); + // } + // } + + // this case cannot be solved easily. the data object returned by the function call has no fixed + // definition. + + return null; + } + + syn ASTNode Designator.declaration(); + + eq ObjectName_Designator.declaration() = getObjectName().declaration(); + eq Substring_Designator.declaration() = getSubstring().getParentString().declaration(); + eq ArrayElement_Designator.declaration() = getArrayElement().declaration(); + eq ArraySection_Designator.declaration() = getArraySection().declaration(); + + syn ASTNode ObjectName.declaration() = getName().lookup(); + + syn ASTNode ParentString.declaration(); + eq VariableNameParentString.declaration() = getVariableName().declaration(); + eq ArrayElementParentString.declaration() = getArrayElement().declaration(); + eq CoindexedNamedObjectParentString.declaration() = getCoindexedNamedObject().declaration(); + eq StructureComponentParentString.declaration() = getStructureComponent().declaration(); + eq ConstantParentString.declaration() = getConstant().declaration(); + + syn ASTNode VariableName.declaration() = getName().lookup(); + syn ASTNode ArrayElement.declaration() = getDataRef().lookup(); + + syn ASTNode ArraySection.declaration() = getDataRef().lookup(); + + syn ASTNode CoindexedNamedObject.declaration() = getDataRef().lookup(); + + syn ASTNode StructureComponent.declaration() = getDataRef().lookup(); + + syn ASTNode Constant.declaration(); + eq LiteralConstant.declaration() = null; + eq NamedConstant.declaration() = getName().lookup(); // =============================================================================================== // DECLARATIONS // =============================================================================================== - syn ASTNode Name.declaration(); - eq Name.declaration() { - java.util.Set<ASTNode> decls = enclosingScope().localDeclarations(); - for(ASTNode decl : decls) { - java.util.Set<Name> names = decl.declaredSimpleNames(); - for (Name name : names) { + syn ASTNode Name.lookup(); + eq Name.lookup() { + ASTNode scope = this.enclosingScope(); + + while (scope != null) { + + java.util.Set<ASTNode> decls = scope.localDeclarations(); + for(ASTNode decl : decls) { + java.util.Set<Name> names = decl.declaredSimpleNames(); + for (Name name : names) { + if (name.getString().equals(this.getString())) { + return decl; + } + } + } + scope = scope.enclosingScope(); + } + // TODO look into COMMON blocks + return null; + } + + syn ASTNode DataRef.lookup() { + ASTNode dataObject; + + // a DataRef has at least one PartRef. first, the first PartRef is resolved with a lookup that + // should return + // - a DerivedTypeDef if it is no the last PartRef if in DataRef + // - any type otherwise + // C609 (R611) Each part-name except the rightmost shall be of derived type. + // [defined type, i.e. lookup() returns DerivedTypeDef] + // those reference a derived type. + int index = 0; + DerivedTypeDef currentTypeDef = null; + + // in the first PartRef, the name is the name of a variable that can be looked up normally. + ASTNode declaration = getPartRef(0).getName().lookup(); + // if the first PartRef is the only one, we are done and just return the lookup result + if (getPartRefList().numChildren() == 1) { + } else { + // otherwise, we extract the name from the lookup result that, incidentally, is the name + // of a data component. We can do this as follows because we know it MUST be a derived + // type + Name dataComponentName = declaration.typeDeclarationStmt().derivedType().getName(); + + // now, for the "inner" PartRefs, we loop the following: + // * find the definition of the derived type + // * find the correct component (comparing with the PartRefs name) + // * find the name of next derived type + for (index = 1; index < getPartRefList().numChildren() - 1; index++) { + // * find the definition of the derived type + DerivedTypeDef derivedType = dataComponentName.lookupType(); + // * find the correct component (comparing with the PartRefs name) + ComponentDecl componentDecl = null; + for (DataComponentDefStmt def : derivedType.dataComponentDefs()) { + // iterate over all names in the DataComponentDefStmts + for (ComponentDecl cDecl : def.getComponentDeclList()) { + if (cDecl.getName().getString().equals(getPartRef(index).getName().getString())) { + componentDecl = cDecl; + } + } + } + // * find the name of next derived type + dataComponentName = componentDecl.typeSpec().getDeclarationTypeSpec().derivedType().getName(); + } + + // now we have the name of the last type spec we need to investigate and only need to look + // up the final Component's type + DerivedTypeDef derivedType = dataComponentName.lookupType(); + // * find the correct component (comparing with the PartRefs name) + ComponentDecl componentDecl = null; + for (DataComponentDefStmt def : derivedType.dataComponentDefs()) { + // iterate over all names in the DataComponentDefStmts + for (ComponentDecl cDecl : def.getComponentDeclList()) { + if (cDecl.getName().getString().equals(getPartRef(index).getName().getString())) { + componentDecl = cDecl; + } + } + } + + return componentDecl.typeSpec(); + + } + return null; + } + + inh DerivedTypeDef DataComponentDefStmt.containingTypeDef(); + eq DerivedTypeDef.getComponentPart().containingTypeDef() = this; + + coll java.util.Set<DataComponentDefStmt> DerivedTypeDef.dataComponentDefs() [new java.util.HashSet<DataComponentDefStmt>()] with add; + + DataComponentDefStmt + contributes this + to DerivedTypeDef.dataComponentDefs() + for containingTypeDef(); + + + // =============================================================================================== + // LOCAL TYPE DECLARATIONS + // =============================================================================================== + + // collection attribute to collect all type declarations in the local scope + coll java.util.Set<DerivedTypeDef> ASTNode.localDerivedTypeDefs() [new java.util.HashSet<DerivedTypeDef>()] with add; + + DerivedTypeDef contributes this + to ASTNode.localDerivedTypeDefs() + for enclosingScope(); + + syn DerivedTypeDef Name.lookupType(); + eq Name.lookupType() { + ASTNode scope = this.enclosingScope(); + + while (scope != null) { + + java.util.Set<DerivedTypeDef> decls = scope.localDerivedTypeDefs(); + for(DerivedTypeDef decl : decls) { + Name name = decl.getDerivedTypeStmt().getTypeName(); if (name.getString().equals(this.getString())) { return decl; } } + scope = scope.enclosingScope(); } return null; } + inh DataComponentDefStmt ComponentDecl.typeSpec(); + eq DataComponentDefStmt.getComponentDecl(int i).typeSpec() = this; + + // =============================================================================================== + // LOCAL DECLARATIONS WITH TYPES + // =============================================================================================== + + syn boolean ASTNode.isTypeDeclaration(); + eq ASTNode.isTypeDeclaration() = false; + eq TypeDeclarationStmt.isTypeDeclaration() = true; + + syn TypeDeclarationStmt ASTNode.typeDeclarationStmt(); + eq ASTNode.typeDeclarationStmt() = null; + eq TypeDeclarationStmt.typeDeclarationStmt() = this; + + syn boolean TypeDeclarationStmt.isDerivedType(); + eq TypeDeclarationStmt.isDerivedType() = getDeclarationTypeSpec().isDerivedType(); + syn DerivedTypeSpec TypeDeclarationStmt.derivedType(); + eq TypeDeclarationStmt.derivedType() = getDeclarationTypeSpec().derivedType(); + + syn boolean DeclarationTypeSpec.isDerivedType(); + eq SimpleDeclarationTypeSpec.isDerivedType() = false; + eq TypeDeclarationTypeSpec.isDerivedType() = getTypeSpec().isDerivedType(); + eq ClassDeclarationTypeSpec.isDerivedType() = hasDerivedTypeSpec(); + syn DerivedTypeSpec DeclarationTypeSpec.derivedType(); + eq SimpleDeclarationTypeSpec.derivedType() = null; + eq TypeDeclarationTypeSpec.derivedType() = getTypeSpec().derivedType(); + eq ClassDeclarationTypeSpec.derivedType() = hasDerivedTypeSpec() ? getDerivedTypeSpec() : null; + + syn boolean TypeSpec.isDerivedType(); + eq TypeSpec.isDerivedType() = false; + eq DerivedTypeSpec.isDerivedType() = true; + syn DerivedTypeSpec TypeSpec.derivedType(); + eq TypeSpec.derivedType() = null; + eq DerivedTypeSpec.derivedType() = this; + + // =============================================================================================== // LOCAL DECLARATIONS // =============================================================================================== diff --git a/Parser/test-data/rewrites/B_Designator_OR_FunctionReference.f90 b/Parser/test-data/rewrites/B_Designator_OR_FunctionReference.f90 index 43d0adf938688d4d7f1f5abe4ede60056233a495..efbe7a8c8d04ffff36920a63fcd53346deb09dd4 100644 --- a/Parser/test-data/rewrites/B_Designator_OR_FunctionReference.f90 +++ b/Parser/test-data/rewrites/B_Designator_OR_FunctionReference.f90 @@ -1,3 +1,18 @@ -real :: a(10) -a(2) = a(1) + + +TYPE FULLNAME + CHARACTER (LEN = 50) FIRST,LAST + +END TYPE PERSON + +TYPE PERSON + INTEGER AGE + TYPE (FULLNAME) NAME +END TYPE PERSON + +TYPE (PERSON) :: CHAIRMAN + +CHAIRMAN%NAME%FIRST = 10 +CHAIRMAN%NAME = 10 + end