Skip to content

Commit

Permalink
Remove module prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
mmhelloworld committed Nov 29, 2024
1 parent 9021e5c commit 89a338d
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Stream;

import static java.io.File.pathSeparator;
Expand All @@ -35,7 +31,6 @@
import static java.nio.file.Files.createTempDirectory;
import static java.nio.file.Files.newOutputStream;
import static java.util.Arrays.asList;
import static java.util.Collections.synchronizedSet;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;

Expand All @@ -54,7 +49,6 @@ public final class AsmGlobalState {
}

private final Map<String, Object> functions;
private final Set<String> untypedFunctions;
private final Set<String> constructors;
private final String programName;
private final Map<String, Object> fcAndDefinitionsByName;
Expand All @@ -63,21 +57,12 @@ public final class AsmGlobalState {
public <T> AsmGlobalState(String programName,
Map<String, Object> fcAndDefinitionsByName) {
this.programName = programName;
functions = new ConcurrentHashMap<>();
untypedFunctions = synchronizedSet(new HashSet<>());
constructors = synchronizedSet(new HashSet<>());
assemblers = new ConcurrentHashMap<>();
functions = new HashMap<>();
constructors = new HashSet<>();
assemblers = new HashMap<>();
this.fcAndDefinitionsByName = fcAndDefinitionsByName;
}

public static void copyRuntimeJar(String directory) {
String runtimeJarFile = Arrays.stream(System.getProperty("java.class.path").split(pathSeparator))
.filter(name -> name.contains(RUNTIME_JAR_NAME))
.findAny()
.orElseThrow(() -> new RuntimeException("Unable to find idris runtime jar"));
copyRuntimeClasses(new File(runtimeJarFile), directory);
}

private static void copyRuntimeClasses(String outputDirectory) {
String packageName = Runtime.class.getPackage().getName();
String packagePath = packageName.replaceAll("[.]", "/");
Expand All @@ -102,27 +87,6 @@ private static void copyRuntimeClass(ClassLoader classLoader, String className,
}
}

private static void copyRuntimeClasses(File file, String directory) {
try (JarFile jarFile = new JarFile(file)) {
Collections.list(jarFile.entries()).stream()
.filter(jarEntry -> !jarEntry.isDirectory() && jarEntry.getName().endsWith(".class"))
.forEach(jarEntry -> copy(jarFile, jarEntry, directory));
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private static void copy(JarFile jarFile, JarEntry jarEntry, String directory) {
Path outputPath = Paths.get(directory, jarEntry.getName());
outputPath.getParent().toFile().mkdirs();
try (InputStream inputStream = new BufferedInputStream(jarFile.getInputStream(jarEntry));
OutputStream outputStream = new BufferedOutputStream(newOutputStream(outputPath))) {
copy(inputStream, outputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private static List<String> getJavaOptions() {
String javaOpts = getProperty("JAVA_OPTS", "-Xss8m");
return asList(javaOpts.split("\\s+"));
Expand Down Expand Up @@ -157,14 +121,6 @@ public synchronized Object getFunction(String name) {
return functions.get(name);
}

public synchronized void addUntypedFunction(String name) {
untypedFunctions.add(name);
}

public synchronized boolean isUntypedFunction(String name) {
return untypedFunctions.contains(name);
}

public synchronized Assembler getAssembler(String name) {
return assemblers.computeIfAbsent(name, key -> new Assembler());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,21 @@

import io.github.mmhelloworld.idrisjvm.runtime.IdrisList;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static java.lang.Character.toUpperCase;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toCollection;

public final class IdrisName {

public static final String CLASS_NAME_FUNCTION_NAME_SEPARATOR = ",";
private static final Map<Character, String> REPLACEMENTS = new HashMap<>();

private IdrisName() {
}

static {
REPLACEMENTS.put(' ', "$s");
REPLACEMENTS.put('!', "$not");
Expand Down Expand Up @@ -55,26 +51,23 @@ public final class IdrisName {
REPLACEMENTS.put(']', "$rsqr");
}

private IdrisName() {
}

public static IdrisList getIdrisFunctionName(String programName, String idrisNamespace, String idrisFunctionName) {
return getIdrisName(programName, idrisNamespace, idrisFunctionName);
return getIdrisName(getRootModuleName(programName), idrisNamespace, idrisFunctionName);
}

public static String getIdrisConstructorClassName(String idrisName) {
return String.join("/", addModulePrefix("main", asList(idrisName.split("/"))));
public static String getIdrisConstructorClassName(String programName, String idrisName) {
return addModulePrefix(getRootModuleName(programName), idrisName);
}

public static String transformCharacters(String value) {
return value
.chars()
.flatMap(c -> REPLACEMENTS.getOrDefault((char) c, String.valueOf((char) c)).chars())
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
StringBuilder builder = new StringBuilder();
for (char c: value.toCharArray()) {
builder.append(transformCharacter(c));
}
return builder.toString();
}

public static String transformCharacter(char c) {
private static String transformCharacter(char c) {
return REPLACEMENTS.getOrDefault(c, String.valueOf(c));
}

Expand All @@ -83,8 +76,8 @@ private static IdrisList getIdrisName(String programName, String idrisNamespace,
return IdrisList.fromIterable(asList(classAndMemberName.getKey(), classAndMemberName.getValue()));
}

private static String join(String value1, String value2) {
return value1 + CLASS_NAME_FUNCTION_NAME_SEPARATOR + value2;
private static String getRootModuleName(String programName) {
return toUpperCase(programName.charAt(0)) + programName.substring(1);
}

private static Entry<String, String> getClassAndMemberName(String programName, String idrisNamespace,
Expand All @@ -99,44 +92,15 @@ private static String getClassName(String programName, String idrisNamespace) {
} else if (idrisNamespace.startsWith("nomangle:")) {
return idrisNamespace.substring("nomangle:".length());
} else {
LinkedList<String> moduleParts =
Stream.of(idrisNamespace.split("/")).collect(toCollection(LinkedList::new));
return String.join("/", addModulePrefix(programName, moduleParts));
return addModulePrefix(programName, idrisNamespace);
}
}

private static List<String> addModulePrefix(String programName, List<String> nameParts) {
int size = nameParts.size();
if (size > 1) {
List<String> packageNameParts = nameParts.subList(1, size - 1);
LinkedList<String> prefixedPackagedNames = packageNameParts.stream()
.map(packageName -> "M_" + packageName)
.collect(toCollection(LinkedList::new));
String rootPackage = nameParts.get(0);
prefixedPackagedNames.add(0, rootPackage.equals(programName) ? rootPackage : "M_" + rootPackage);
String className = nameParts.get(size - 1);
prefixedPackagedNames.add(className);
return prefixedPackagedNames;
private static String addModulePrefix(String programName, String name) {
if (name.indexOf('/') < 0) {
return programName + "/" + name;
} else {
return asList(programName, nameParts.get(0));
return name;
}
}

private static <T> LinkedList<T> add(LinkedList<T> items, T item) {
items.add(item);
return items;
}

private static <T> LinkedList<T> tail(LinkedList<T> items) {
return new LinkedList<>(items.subList(1, items.size()));
}

private static Stream<String> getIdrisModuleNameFromFileName(String fileName) {
Path path = Paths.get(fileName.replaceAll("^\\.+|\\.idr$", ""));
Path module = path.normalize();
return IntStream.range(0, module.getNameCount())
.mapToObj(module::getName)
.map(Path::toString);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,33 @@

public final class IdrisNameTest {

static Stream<Arguments> getFunctionName() {
static Stream<Arguments> getIdrisFunctionName() {
return Stream.of(
arguments("Data/List", "take", IdrisList.fromIterable(asList("M_Data/List", "take"))),
arguments("Main", "bar", IdrisList.fromIterable(asList("main/Main", "bar"))),
arguments("Foo", "bar", IdrisList.fromIterable(asList("main/Foo", "bar"))),
arguments("Main/Foo", "bar", IdrisList.fromIterable(asList("M_Main/Foo", "bar"))),
arguments("Main/Foo/Bar/Baz", "bar", IdrisList.fromIterable(asList("M_Main/M_Foo/M_Bar/Baz", "bar"))));
arguments("Data/List", "take", IdrisList.fromIterable(asList("Data/List", "take"))),
arguments("Main", "bar", IdrisList.fromIterable(asList("Main/Main", "bar"))),
arguments("Foo", "bar", IdrisList.fromIterable(asList("Main/Foo", "bar"))),
arguments("Main/Foo", "bar", IdrisList.fromIterable(asList("Main/Foo", "bar"))),
arguments("Main/Foo/Bar/Baz", "bar", IdrisList.fromIterable(asList("Main/Foo/Bar/Baz", "bar"))));
}

static Stream<Arguments> getConstructorClassName() {
return Stream.of(
arguments("Data/List/Take", "M_Data/M_List/Take"),
arguments("Prelude/Foo", "M_Prelude/Foo"),
arguments("Prelude", "main/Prelude")
);
arguments("Data/List/Take", "Data/List/Take"),
arguments("Prelude/Foo", "Prelude/Foo"),
arguments("Prelude", "Main/Prelude"));
}

@ParameterizedTest
@MethodSource
void getFunctionName(String moduleName, String functionName, IdrisList idrisClassFunctionName) {
void getIdrisFunctionName(String moduleName, String functionName, IdrisList idrisClassFunctionName) {
assertThat(IdrisName.getIdrisFunctionName("main", moduleName, functionName))
.isEqualTo(idrisClassFunctionName);
}

@ParameterizedTest
@MethodSource
void getConstructorClassName(String idrisConstructorName, String transformedConstructorName) {
assertThat(IdrisName.getIdrisConstructorClassName(idrisConstructorName))
assertThat(IdrisName.getIdrisConstructorClassName("main", idrisConstructorName))
.isEqualTo(transformedConstructorName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ public static String getStackTraceString() {
public static void free(Object object) {
}

public static Object unwrap(Object possibleThunk) {
// Method to be removed in next version
return possibleThunk;
}

public static Object force(Object delayed) {
return ((Delayed)delayed).evaluate();
}
Expand Down
26 changes: 26 additions & 0 deletions libs/base/Java/Util/Function.idr
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ namespace BiFunction
apply : HasIO io => {a, b, c: Type} -> (a -> b -> PrimIO c) -> (x: a) -> (y: b) -> io c
apply {a} {b} {c} f x y = primIO $ prim_apply (jlambda f) x y

namespace ToIntFunction

public export %inline
ToIntFunction : Type -> Type
ToIntFunction a = (Struct "java/util/function/ToIntFunction applyAsInt" [("<>", a)], Object -> PrimIO Int)

%foreign "jvm:.applyAsInt"
prim_applyAsInt : ToIntFunction a -> a -> PrimIO Int

public export %inline
applyAsInt : HasIO io => ToIntFunction a -> a -> io Int
applyAsInt f a = primIO $ prim_applyAsInt f a

namespace Predicate

public export %inline
Expand All @@ -42,6 +55,19 @@ namespace Predicate
test : HasIO io => Predicate a -> a -> io Bool
test f a = primIO $ prim_test f a

namespace BiPredicate

public export %inline
BiPredicate : Type -> Type -> Type
BiPredicate a b = (Struct "java/util/function/BiPredicate test" [("<>", a), ("<>", b)], Object -> Object -> PrimIO Bool)

%foreign "jvm:.test"
prim_test : BiPredicate a b -> a -> b -> PrimIO Bool

public export %inline
test : HasIO io => BiPredicate a b -> a -> b -> io Bool
test f a b = primIO $ prim_test f a b

namespace Supplier

public export %inline
Expand Down
17 changes: 5 additions & 12 deletions src/Compiler/Jvm/Codegen.idr
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,6 @@ isInterfaceInvocation : InferredType -> Bool
isInterfaceInvocation (IRef _ Interface _) = True
isInterfaceInvocation _ = False

assembleZero : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> Core ()
assembleZero isTailCall returnType = do
iconst 0
asmCast IInt returnType
when isTailCall $ asmReturn returnType

assembleNil : {auto stateRef: Ref AsmState AsmState} -> (isTailCall: Bool) -> InferredType -> Core ()
assembleNil isTailCall returnType = do
field GetStatic idrisNilClass "INSTANCE" "Lio/github/mmhelloworld/idrisjvm/runtime/IdrisList$Nil;"
Expand Down Expand Up @@ -483,8 +477,8 @@ mutual
ldc $ DoubleConst value
asmCast IDouble returnType
when isTailCall $ asmReturn returnType
assembleExpr isTailCall returnType (NmPrimVal _ _) = assembleZero isTailCall returnType
assembleExpr isTailCall returnType (NmErased _) = assembleZero isTailCall returnType
assembleExpr isTailCall returnType (NmPrimVal _ _) = assembleInt isTailCall returnType 0
assembleExpr isTailCall returnType (NmErased _) = assembleInt isTailCall returnType 0
assembleExpr isTailCall returnType (NmCrash _ msg) = do
ldc $ StringConst msg
invokeMethod InvokeStatic runtimeClass "crash" "(Ljava/lang/String;)Ljava/lang/Object;" False
Expand Down Expand Up @@ -534,7 +528,7 @@ mutual
-> InferredType -> FC -> Name -> (tag : Maybe Int) -> List NamedCExp -> Core ()
assembleCon isTailCall returnType fc name tag args = do
let fileName = fst $ getSourceLocationFromFc fc
let constructorClassName = getIdrisConstructorClassName (jvmSimpleName name)
let constructorClassName = getIdrisConstructorClassName !getProgramName (jvmSimpleName name)
let constructorType = maybe inferredStringType (const IInt) tag
new constructorClassName
dup
Expand Down Expand Up @@ -1651,7 +1645,7 @@ mutual
where
conAltHashCodeExpr : FC -> (Int, NamedConAlt) -> Core (Int, Int, NamedConAlt)
conAltHashCodeExpr fc positionAndAlt@(position, MkNConAlt name _ _ _ _) =
case hashCode (Str $ getIdrisConstructorClassName (jvmSimpleName name)) of
case hashCode (Str $ getIdrisConstructorClassName !getProgramName (jvmSimpleName name)) of
Just hashCodeValue => pure (hashCodeValue, position, snd positionAndAlt)
Nothing => asmCrash ("Constructor " ++ show name ++ " cannot be compiled to 'Switch'.")

Expand All @@ -1675,7 +1669,7 @@ mutual
labelStart label
addLineNumber lineNumberStart label
loadVar !getVariableTypes inferredStringType inferredStringType constantExprVariableIndex
ldc $ StringConst $ getIdrisConstructorClassName (jvmSimpleName name)
ldc $ StringConst $ getIdrisConstructorClassName !getProgramName (jvmSimpleName name)
invokeMethod InvokeVirtual constantClass "equals" "(Ljava/lang/Object;)Z" False
ifeq nextLabel
iconst position
Expand Down Expand Up @@ -1742,7 +1736,6 @@ mutual
applyParameter typesByIndex isIoApplication index parameterType = do
loadArgument
invokeMethod InvokeInterface "java/util/function/Function" "apply" "(Ljava/lang/Object;)Ljava/lang/Object;" True
invokeMethod InvokeStatic runtimeClass "unwrap" "(Ljava/lang/Object;)Ljava/lang/Object;" False
where
loadArgument : Core ()
loadArgument =
Expand Down
Loading

0 comments on commit 89a338d

Please sign in to comment.