Skip to content

Commit

Permalink
Add TypedValue.fieldValueAs
Browse files Browse the repository at this point in the history
  • Loading branch information
julianhyde committed Dec 24, 2023
1 parent c8b13e2 commit f0e0548
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 24 deletions.
12 changes: 5 additions & 7 deletions src/main/java/net/hydromatic/morel/compile/Resolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -507,13 +507,11 @@ Object valueOf(Core.Exp exp) {
final Core.RecordSelector recordSelector =
(Core.RecordSelector) apply.fn;
final Object o = valueOf(apply.arg);
@SuppressWarnings("unchecked") List<Object> list =
o instanceof List
? (List<Object>) o
: o instanceof Codes.TypedValue
? ((Codes.TypedValue) o).valueAs(List.class)
: null;
if (list != null) {
if (o instanceof Codes.TypedValue) {
return ((Codes.TypedValue) o).fieldValueAs(recordSelector.slot,
Object.class);
} else if (o instanceof List) {
@SuppressWarnings("unchecked") List<Object> list = (List<Object>) o;
return list.get(recordSelector.slot);
}
}
Expand Down
20 changes: 4 additions & 16 deletions src/main/java/net/hydromatic/morel/compile/TypeResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,9 @@ private Resolved deduceType_(@Nullable Session session, Environment env,
applies.add(apply);
}
});
final int originalExpandCount = typeSystem.expandCount.get();
if (!applies.isEmpty()) {
for (Ast.Apply apply : applies) {
expandField(session, env, typeMap, apply);
expandField(env, apply);
}
} else {
checkNoUnresolvedFieldRefs(node2, typeMap);
Expand All @@ -210,27 +209,16 @@ private static boolean isProgressive(Type type) {
.containsKey(ProgressiveRecordType.DUMMY);
}

private Codes.@Nullable TypedValue expandField(@Nullable Session session,
Environment env, TypeMap typeMap, Ast.Exp exp) {
private Codes.@Nullable TypedValue expandField(Environment env, Ast.Exp exp) {
switch (exp.op) {
case APPLY:
final Ast.Apply apply = (Ast.Apply) exp;
if (apply.fn.op == Op.RECORD_SELECTOR) {
final Ast.RecordSelector selector = (Ast.RecordSelector) apply.fn;
final Codes.TypedValue typedValue =
expandField(session, env, typeMap, apply.arg);
final Codes.TypedValue typedValue = expandField(env, apply.arg);
if (typedValue != null) {
typedValue.discoverField(typeSystem, selector.name);
final RecordLikeType type =
(RecordLikeType) typedValue.typeKey().toType(typeSystem);
int i =
ImmutableList.copyOf(type.argNameTypes().keySet())
.indexOf(selector.name);
if (i >= 0) { // TODO: add a method TypedValue.fieldValue(name)
@SuppressWarnings("unchecked")
final List<Codes.TypedValue> list = typedValue.valueAs(List.class);
return list.get(i);
}
return typedValue.fieldValueAs(selector.name, Codes.TypedValue.class);
}
}
return null;
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/net/hydromatic/morel/eval/Codes.java
Original file line number Diff line number Diff line change
Expand Up @@ -3720,7 +3720,18 @@ public interface Positioned extends Applicable {

/** A value that knows its own type. */
public interface TypedValue {
/** Returns the value cast as a particular type. */
<V> V valueAs(Class<V> clazz);

/** Returns the value of a field, cast as a particular type. */
default <V> V fieldValueAs(String fieldName, Class<V> clazz) {
throw new UnsupportedOperationException("not a record");
}

default <V> V fieldValueAs(int fieldIndex, Class<V> clazz) {
throw new UnsupportedOperationException("not a record");
}

Type.Key typeKey();

/** Tries to expand the type to include the given field name.
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/net/hydromatic/morel/eval/Files.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,15 @@ private static class Directory extends AbstractList<File> implements File {
}
throw new IllegalArgumentException("not a " + clazz);
}
}

@Override public <V> V fieldValueAs(String fieldName, Class<V> clazz) {
return clazz.cast(entries.get(fieldName));
}

@Override public <V> V fieldValueAs(int fieldIndex, Class<V> clazz) {
return clazz.cast(Iterables.get(entries.values(), fieldIndex));
}
}

/** File that is not a directory, and can be parsed into a set of records. */
private static class DataFile extends AbstractFile {
Expand Down

0 comments on commit f0e0548

Please sign in to comment.