Skip to content

Commit

Permalink
Add Type.isProgressive
Browse files Browse the repository at this point in the history
  • Loading branch information
julianhyde committed Dec 25, 2023
1 parent 1b58f83 commit 5f9eb43
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 43 deletions.
5 changes: 1 addition & 4 deletions src/main/java/net/hydromatic/morel/compile/Pretty.java
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,7 @@ private StringBuilder prettyType(StringBuilder buf, int indent, int[] lineEnd,
case RECORD_TYPE:
case PROGRESSIVE_RECORD_TYPE:
final RecordType recordType = (RecordType) typeVal.type;
final boolean progressive =
type.op() == Op.PROGRESSIVE_RECORD_TYPE
|| recordType.argNameTypes.containsKey(
ProgressiveRecordType.DUMMY);
final boolean progressive = typeVal.type.isProgressive();
buf.append("{");
start = buf.length();
recordType.argNameTypes.forEach((name, elementType) -> {
Expand Down
17 changes: 6 additions & 11 deletions src/main/java/net/hydromatic/morel/compile/Resolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import net.hydromatic.morel.type.FnType;
import net.hydromatic.morel.type.ForallType;
import net.hydromatic.morel.type.ListType;
import net.hydromatic.morel.type.ProgressiveRecordType;
import net.hydromatic.morel.type.RecordLikeType;
import net.hydromatic.morel.type.RecordType;
import net.hydromatic.morel.type.TupleType;
Expand Down Expand Up @@ -416,13 +415,9 @@ private Core.Apply toCore(Ast.Apply apply) {
makeProgressive(coreArg), recordSelector.name);
if (type.op() == Op.TY_VAR
&& coreFn.type.op() == Op.FUNCTION_TYPE
|| type instanceof RecordType
&& ((RecordLikeType) type).argNameTypes().containsKey(
ProgressiveRecordType.DUMMY)
|| type.isProgressive()
|| type instanceof ListType
&& ((ListType) type).elementType instanceof RecordType
&& ((RecordLikeType) ((ListType) type).elementType)
.argNameTypes().containsKey(ProgressiveRecordType.DUMMY)) {
&& ((ListType) type).elementType.isProgressive()) {
// If we are dereferencing a field in a progressive type, the type
// available now may be more precise than the deduced type.
type = ((FnType) coreFn.type).resultType;
Expand All @@ -438,7 +433,7 @@ private Core.Apply toCore(Ast.Apply apply) {
* type. */
private RecordLikeType makeProgressive(Core.Exp coreArg) {
final RecordLikeType recordLikeType = (RecordLikeType) coreArg.type;
if (recordLikeType.argNameTypes().containsKey(ProgressiveRecordType.DUMMY)) {
if (coreArg.type.isProgressive()) {
Object o = valueOf(coreArg);
if (o instanceof Codes.TypedValue) {
final Codes.TypedValue typedValue = (Codes.TypedValue) o;
Expand Down Expand Up @@ -701,13 +696,13 @@ private static boolean subsumes(Type actualType, Type expectedType) {
if (expectedType.op() != Op.RECORD_TYPE) {
return false;
}
if (actualType.isProgressive()) {
return true;
}
final SortedMap<String, Type> actualMap =
((RecordType) actualType).argNameTypes();
final SortedMap<String, Type> expectedMap =
((RecordType) expectedType).argNameTypes();
if (actualMap.containsKey(ProgressiveRecordType.DUMMY)) {
return true;
}
final Iterator<Map.Entry<String, Type>> actualIterator =
actualMap.entrySet().iterator();
final Iterator<Map.Entry<String, Type>> expectedIterator =
Expand Down
9 changes: 2 additions & 7 deletions src/main/java/net/hydromatic/morel/compile/TypeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package net.hydromatic.morel.compile;

import net.hydromatic.morel.ast.AstNode;
import net.hydromatic.morel.type.ProgressiveRecordType;
import net.hydromatic.morel.type.RecordType;
import net.hydromatic.morel.type.Type;
import net.hydromatic.morel.type.TypeSystem;
Expand Down Expand Up @@ -98,12 +97,8 @@ public boolean typeIsVariable(AstNode node) {
final Unifier.Term term = nodeTypeTerms.get(node);
if (term instanceof Unifier.Variable) {
final Type type = termToType(term);
if (type instanceof TypeVar
|| type instanceof RecordType
&& ((RecordType) type).argNameTypes.containsKey(
ProgressiveRecordType.DUMMY)) {
return true;
}
return type instanceof TypeVar
|| type.isProgressive();
}
return false;
}
Expand Down
12 changes: 1 addition & 11 deletions src/main/java/net/hydromatic/morel/compile/TypeResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
import net.hydromatic.morel.type.Keys;
import net.hydromatic.morel.type.ListType;
import net.hydromatic.morel.type.PrimitiveType;
import net.hydromatic.morel.type.ProgressiveRecordType;
import net.hydromatic.morel.type.RecordLikeType;
import net.hydromatic.morel.type.RecordType;
import net.hydromatic.morel.type.TupleType;
import net.hydromatic.morel.type.Type;
Expand Down Expand Up @@ -186,7 +184,7 @@ private Resolved deduceType_(@Nullable Session session, Environment env,
List<Ast.Apply> applies = new ArrayList<>();
forEachUnresolvedField(node2, typeMap, apply -> {
final Type type = typeMap.getType(apply.arg);
if (isProgressive(type)) {
if (type.isProgressive()) {
applies.add(apply);
}
});
Expand All @@ -201,14 +199,6 @@ private Resolved deduceType_(@Nullable Session session, Environment env,
}
}

// TODO: centralize and simplify the following logic
private static boolean isProgressive(Type type) {
return type instanceof ProgressiveRecordType
|| type instanceof RecordLikeType
&& ((RecordLikeType) type).argNameTypes()
.containsKey(ProgressiveRecordType.DUMMY);
}

private Codes.@Nullable TypedValue expandField(Environment env, Ast.Exp exp) {
switch (exp.op) {
case APPLY:
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/net/hydromatic/morel/type/RecordLikeType.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,6 @@ public interface RecordLikeType extends Type {
/** Returns the type of the {@code i}th field, or throws. */
Type argType(int i);

/** Returns whether this type is progressive.
*
* <p>Progressive types are records, but can have additional fields each time
* you look.
*
* <p>The "file" value is an example. */
default boolean isProgressive() {
return false;
}

/** Returns a {@link net.hydromatic.morel.eval.Codes.TypedValue} if this
* type wraps a single dynamically typed value, otherwise null. */
default Codes.@Nullable TypedValue asTypedValue() {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/net/hydromatic/morel/type/RecordType.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public Key key() {
: (RecordType) typeSystem.recordType(argNameTypes2.build());
}

@Override public boolean isProgressive() {
return argNameTypes.containsKey(ProgressiveRecordType.DUMMY);
}

/** Ordering that compares integer values numerically,
* string values lexicographically,
* and integer values before string values.
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/net/hydromatic/morel/type/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ default Type substitute(TypeSystem typeSystem, List<? extends Type> types) {
});
}

/** Returns whether this type is progressive.
*
* <p>Progressive types are records, but can have additional fields each time
* you look.
*
* <p>The "file" value is an example. */
default boolean isProgressive() {
return false;
}

/** Structural identifier of a type. */
abstract class Key {
public final Op op;
Expand Down

0 comments on commit 5f9eb43

Please sign in to comment.