Skip to content

Commit

Permalink
[NF] Various fixes.
Browse files Browse the repository at this point in the history
- Fixed duplicate element handling when inheriting the same element from
  two base classes, where the element is a duplicate in one base class
  but not the other.
- Added missing constant evaluation of unary minus for arrays.

Belonging to [master]:
  - OpenModelica/OMCompiler#2483
  - OpenModelica/OpenModelica-testsuite#968
  • Loading branch information
perost authored and OpenModelica-Hudson committed May 31, 2018
1 parent afc94ce commit c3468c0
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 39 deletions.
6 changes: 6 additions & 0 deletions Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -879,6 +879,12 @@ algorithm
exp := match exp1
case Expression.INTEGER() then Expression.INTEGER(-exp1.value);
case Expression.REAL() then Expression.REAL(-exp1.value);
case Expression.ARRAY()
algorithm
exp1.elements := list(evalUnaryMinus(e) for e in exp1.elements);
then
exp1;

else
algorithm
exp := Expression.UNARY(Operator.makeUMinus(Type.UNKNOWN()), exp1);
Expand Down
98 changes: 61 additions & 37 deletions Compiler/NFFrontEnd/NFClassTree.mo
Expand Up @@ -75,6 +75,12 @@ public
case IMPORT() then entry.index;
end match;
end index;

function isEqual
input Entry entry1;
input Entry entry2;
output Boolean isEqual = index(entry1) == index(entry2);
end isEqual;
end Entry;

import BaseAvlTree;
Expand Down Expand Up @@ -152,6 +158,15 @@ public
output Entry entry = ENTRY(lentry, NONE(), {}, EntryType.ENTRY);
end newEntry;

function idExistsInEntry
input LookupTree.Entry id;
input Entry entry;
output Boolean exists;
algorithm
exists := LookupTree.Entry.isEqual(id, entry.entry) or
List.exist(entry.children, function idExistsInEntry(id = id));
end idExistsInEntry;

annotation(__OpenModelica_Interface="util");
end DuplicateTree;

Expand Down Expand Up @@ -1665,6 +1680,7 @@ public
DuplicateTree.Entry dup_entry;
Integer new_id = LookupTree.Entry.index(newEntry);
Integer old_id = LookupTree.Entry.index(oldEntry);
DuplicateTree.EntryType ty;
algorithm
dups := Mutable.access(duplicates);
opt_dup_entry := DuplicateTree.getOpt(dups, name);
Expand All @@ -1681,48 +1697,56 @@ public

dups := DuplicateTree.add(dups, name, dup_entry);
Mutable.update(duplicates, dups);
elseif isNone(DuplicateTree.getOpt(extDuplicates, name)) then
// If a duplicate entry does exist, but not in the extends node's duplicate
// tree, then we need to add the inherited element to the existing entry.
// This happens when the element is not a duplicate in its own scope.
else
SOME(dup_entry) := opt_dup_entry;

// TODO: Change this to an if-statement when compiler bug #4502 is fixed.
() := match dup_entry.ty
case DuplicateTree.EntryType.REDECLARE
algorithm
// If the existing entry is for a redeclare, then the position of
// the element doesn't matter and the new entry should be added as
// a child to the redeclare.
ty := dup_entry.ty;

// Here it's possible for either the new or the old entry to not exist in the duplicate entry.
// The new might not exist simply because it hasn't been added yet, while the old might not
// exist because it wasn't a duplicate in its own scope. At least one of them must exist though,
// since duplicate entries are added for any name occurring more than once.
if not DuplicateTree.idExistsInEntry(newEntry, dup_entry) then
if ty == DuplicateTree.EntryType.REDECLARE then
// If the existing entry is for a redeclare, then the position of the element
// doesn't matter and the new entry should be added as a child to the redeclare.
entry := newEntry;
dup_entry.children := DuplicateTree.newEntry(newEntry) :: dup_entry.children;
else
// Otherwise we need to keep the 'first' element as the parent.
// Note that this only actually works for components, since we don't
// preserve the order for classes. But which class we choose shouldn't
// matter since they should be identical. We might also compare e.g. a
// component to a class here, but that will be caught in checkDuplicates.
if new_id < old_id then
entry := newEntry;
dup_entry := DuplicateTree.Entry.ENTRY(newEntry, NONE(),
DuplicateTree.newEntry(oldEntry) :: dup_entry.children, dup_entry.ty);
else
entry := oldEntry;
dup_entry.children := DuplicateTree.newEntry(newEntry) :: dup_entry.children;
then
();
end if;
end if;

dups := DuplicateTree.update(dups, name, dup_entry);
Mutable.update(duplicates, dups);
elseif not DuplicateTree.idExistsInEntry(oldEntry, dup_entry) then
// Same as above but we add the old entry instead.
if ty == DuplicateTree.EntryType.REDECLARE or new_id < old_id then
entry := newEntry;
dup_entry.children := DuplicateTree.newEntry(oldEntry) :: dup_entry.children;
else
algorithm
// Otherwise we need to keep the 'first' element as the parent.
// Note that this only actually works for components, since we don't
// preserve the order for classes. But which class we choose shouldn't
// matter since they should be identical. We might also compare e.g. a
// component to a class here, but that will be caught in checkDuplicates.
if new_id < old_id then
entry := newEntry;
dup_entry := DuplicateTree.Entry.ENTRY(newEntry, NONE(),
DuplicateTree.newEntry(oldEntry) :: dup_entry.children, dup_entry.ty);
else
entry := oldEntry;
dup_entry.children := DuplicateTree.newEntry(newEntry) :: dup_entry.children;
end if;
then
();
end match;
entry := newEntry;
dup_entry := DuplicateTree.Entry.ENTRY(newEntry, NONE(),
DuplicateTree.newEntry(oldEntry) :: dup_entry.children, dup_entry.ty);
end if;

dups := DuplicateTree.update(dups, name, dup_entry);
Mutable.update(duplicates, dups);
else
// If an entry does exist in both duplicate tree, then it's already been
// added by expandExtends and nothing more needs to be done here.
entry := if new_id < old_id then newEntry else oldEntry;
dups := DuplicateTree.update(dups, name, dup_entry);
Mutable.update(duplicates, dups);
else
// If both the old and the new entry already exists, which can happen if the
// new entry was added by expandExtents, then we don't need to add anything.
entry := if new_id < old_id then newEntry else oldEntry;
end if;
end if;
end addInheritedElementConflict;

Expand Down
1 change: 0 additions & 1 deletion Compiler/NFFrontEnd/NFType.mo
Expand Up @@ -368,7 +368,6 @@ public
isNumeric := match ty
case REAL() then true;
case INTEGER() then true;
case FUNCTION() then isBasicNumeric(ty.resultType);
else false;
end match;
end isBasicNumeric;
Expand Down
1 change: 0 additions & 1 deletion Compiler/NFFrontEnd/NFTypeCheck.mo
Expand Up @@ -1689,7 +1689,6 @@ algorithm
if matchKind <> MatchKind.NOT_COMPATIBLE then
matchKind := MatchKind.PLUG_COMPATIBLE;
end if;

then
();

Expand Down

0 comments on commit c3468c0

Please sign in to comment.