Skip to content

Commit 8724705

Browse files
committed
Handle non-exhaustive patterns
1 parent 0021f80 commit 8724705

File tree

10 files changed

+52
-42
lines changed

10 files changed

+52
-42
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ env:
1212
before_install:
1313
- docker pull mmhelloworld/idris:1.3.1
1414
- mkdir -p $HOME/bin/idris-packages $IDRIS_JVM_HOME
15-
- wget https://github.com/mmhelloworld/idris-jvm/releases/download/v1.0-SNAPSHOT-20181103/idris-jvm.zip
15+
- wget https://github.com/mmhelloworld/idris-jvm/releases/download/v1.0-SNAPSHOT-20181129/idris-jvm.zip
1616
- unzip -o idris-jvm.zip -d $HOME/bin
1717
- export PATH=`pwd`/bin/travis:$IDRIS_JVM_HOME/codegen/bin:$HOME/.local/bin:$PATH
1818
- export PROJECT_ROOT=`pwd`

idris-jvm-core/src/main/idris/IdrisJvm/Core/Codegen.idr

+19-3
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ group n xs =
3737
let (ys, zs) = splitAt n xs
3838
in ys :: group n zs
3939

40-
splitApplyFunction : SDecl -> List SDecl
41-
splitApplyFunction (SFun fname args n (SChkCase var cases)) =
40+
splitApplyFunction : String -> List String -> Int -> LVar -> List SAlt -> List SDecl
41+
splitApplyFunction fname args n var cases =
4242
let cs = group 100 cases
4343
len = List.length cs
4444
in map (callNextFn fname args n var len) . List.zip [0 .. pred len] $ cs where
@@ -56,7 +56,7 @@ splitApplyFunction (SFun fname args n (SChkCase var cases)) =
5656
splitLargeFunctions : List SDecl -> List SDecl
5757
splitLargeFunctions decls = decls >>= f where
5858
f : SDecl -> List SDecl
59-
f decl@(SFun "{APPLY_0}" _ _ _) = splitApplyFunction decl
59+
f decl@(SFun "{APPLY_0}" args n (SChkCase var cases)) = splitApplyFunction "{APPLY_0}" args n var cases
6060
f decl = [decl]
6161

6262
inferFuns : SortedMap JMethodName (InferredType, InferredTypeStore)
@@ -72,13 +72,29 @@ inferFuns initial decls = go SortedMap.empty decls where
7272
newAcc = SortedMap.insert fname (retTy, argTys) acc
7373
in go newAcc rest
7474

75+
createMainMethod : String -> JMethodName -> Asm ()
76+
createMainMethod signature (MkJMethodName className methodName) = do
77+
CreateMethod [Public, Static] className "main" "([Ljava/lang/String;)V" Nothing Nothing [] []
78+
MethodCodeStart
79+
Aload 0
80+
InvokeMethod InvokeStatic (rtClass "Runtime") "setProgramArgs" "([Ljava/lang/String;)V" False
81+
InvokeMethod InvokeStatic className methodName signature False
82+
Pop
83+
Return
84+
MaxStackAndLocal (-1) (-1)
85+
MethodCodeEnd
86+
7587
generateMethods' : Assembler -> List SDecl -> List ExportIFace -> JVM_IO ()
7688
generateMethods' assembler decls exports = do
7789
let smallDecls = splitLargeFunctions decls
7890
let functionTypesByNameStage1 = inferFuns SortedMap.empty smallDecls
7991
let functionTypesByName = inferFuns functionTypesByNameStage1 smallDecls
8092
types <- generateMethodsWithTypes functionTypesByName smallDecls
8193
generateExportsWithTypes types exports
94+
let asmState = MkAsmState [] types SortedMap.empty IUnknown
95+
(_, _) <- runAsm asmState assembler
96+
(createMainMethod "()Lio/github/mmhelloworld/idrisjvm/runtime/Thunk;" (jname "{runMain_0}"))
97+
pure ()
8298
where
8399
generateMethodsWithTypes : SortedMap JMethodName (InferredType, InferredTypeStore) -> List SDecl
84100
-> JVM_IO (SortedMap JMethodName (InferredType, InferredTypeStore))

idris-jvm-core/src/main/idris/IdrisJvm/Core/Function.idr

+12-5
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,15 @@ mutual
166166
cgBody ret (SApp False f args) = cgSApp ret False f args
167167

168168
cgBody ret (SLet i v sc) = do
169-
locTys <- GetFunctionLocTypes
170-
let iTy = getLocTy locTys i
171-
cgBody (\vTy => storeVar vTy iTy i) v
172-
cgBody ret sc
169+
locTys <- GetFunctionLocTypes
170+
let iTy = getLocTy locTys i
171+
assign iTy
172+
cgBody ret sc
173+
where
174+
assign : InferredType -> Asm ()
175+
assign iTy = case v of
176+
SNothing => do Aconstnull; storeVar inferredObjectType iTy i
177+
_ => cgBody (\vTy => storeVar vTy iTy i) v
173178

174179
cgBody ret (SUpdate _ e) = cgBody ret e
175180

@@ -240,7 +245,9 @@ mutual
240245

241246
cgBody ret (SOp op args) = cgOp ret op args
242247

243-
cgBody ret SNothing = do Aconstnull; ret inferredObjectType
248+
cgBody ret SNothing = do
249+
invokeError "Unexpected case encountered. This could be due to non-exhaustive patterns."
250+
ret inferredObjectType
244251

245252
cgBody ret (SError x) = do invokeError (show x); ret IUnknown
246253

idris-jvm-core/src/main/java/IdrisJvm/Core/Assembler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public void classCodeEnd(String outputClassFileDir) {
261261
cws.entrySet().parallelStream().forEach(e -> {
262262
String className = e.getKey();
263263
ClassWriter classWriter = e.getValue();
264-
LOGGER.info(" writing class file {} in directory {}", className, outputClassFileDir);
264+
LOGGER.info("Writing class file {} in directory {}", className, outputClassFileDir);
265265
File outFile = new File(outputClassFileDir, className + ".class");
266266
new File(outFile.getParent()).mkdirs();
267267
try (OutputStream out = new FileOutputStream(outFile)) {

idris-jvm-core/src/main/java/IdrisJvm/Core/IdrisToJavaNameConverter.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public class IdrisToJavaNameConverter {
4242
replacements.put('|', "pipe");
4343
replacements.put('}', "rbrace");
4444
replacements.put('~', "tilde");
45-
4645
}
4746

4847
private static final String DEFAULT_PACKAGE_NAME = "main";
@@ -95,7 +94,7 @@ private static String createClassName(final String className) {
9594
return DEFAULT_CLASS_NAME;
9695
} else if (className.contains(".")) {
9796
return className.replaceAll("\\.", "/")
98-
.replaceAll("([^/]+)/", "I\\$$1/");
97+
.replaceAll("([^/]+)/", "I\\_$1/");
9998
} else {
10099
return DEFAULT_PACKAGE_NAME + "/" + className;
101100
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
world!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module Main
2+
3+
main : IO ()
4+
main = do
5+
putStrLn "world!"

idris-jvm-runtime/src/main/java/io/github/mmhelloworld/idrisjvm/runtime/Runtime.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,7 @@ public static Object unwrap(Object value) {
190190

191191
public static int constructorIndex(Object obj) {
192192
final int constructor;
193-
if (obj == null) {
194-
constructor = -1;
195-
} else if (obj instanceof IdrisObject) {
193+
if (obj instanceof IdrisObject) {
196194
constructor = ((IdrisObject) obj).constructorId;
197195
} else if (obj instanceof Integer) {
198196
constructor = (int) obj;

idris-jvm-runtime/src/main/java/io/github/mmhelloworld/idrisjvm/runtime/Util.java

+11-7
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,18 @@ public static int asInt(Object m) {
6868
}
6969

7070
public static boolean equals(Object a, Object b) {
71-
if (a.getClass().isAssignableFrom(b.getClass())) {
72-
return Objects.equals(a, b);
73-
} else if (a instanceof BigInteger && b instanceof Integer) {
74-
return a.equals(BigInteger.valueOf((Integer) b));
75-
} else if (a instanceof Integer && b instanceof BigInteger) {
76-
return b.equals(BigInteger.valueOf((Integer) a));
71+
boolean isEqual = Objects.equals(a, b);
72+
73+
if (isEqual) {
74+
return true;
7775
} else {
78-
return Objects.equals(a, b);
76+
if (a instanceof BigInteger && b instanceof Integer) {
77+
return Objects.equals(a, BigInteger.valueOf((Integer) b));
78+
} else if (a instanceof Integer && b instanceof BigInteger) {
79+
return Objects.equals(b, BigInteger.valueOf((Integer) a));
80+
} else {
81+
return false;
82+
}
7983
}
8084
}
8185

idris-jvm-server/src/main/java/io/github/mmhelloworld/idrisjvm/CodegenController.java

-20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.github.mmhelloworld.idrisjvm;
22

33
import IdrisJvm.Core.Assembler;
4-
import IdrisJvm.Core.IdrisToJavaNameConverter;
54
import IdrisJvm.Core.export.Codegen;
65
import IdrisJvm.IR.export.ExportIFace;
76
import IdrisJvm.IR.export.SDecl;
@@ -32,10 +31,6 @@
3231
import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
3332
import static com.fasterxml.jackson.core.JsonToken.END_OBJECT;
3433
import static java.util.Arrays.asList;
35-
import static java.util.Collections.emptyList;
36-
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
37-
import static org.objectweb.asm.Opcodes.ACC_STATIC;
38-
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
3934
import static org.springframework.web.bind.annotation.RequestMethod.POST;
4035

4136
@RestController
@@ -63,7 +58,6 @@ public void compile(@RequestBody String[] args) {
6358
JsonParser parser = jsonfactory.createParser(source);
6459
Assembler assembler = new Assembler();
6560
codegen(parser, assembler);
66-
addMainMethod(assembler);
6761
assembler.classCodeEnd(getOutputFile(argsList).getPath());
6862
parser.close();
6963
} catch (Exception e) {
@@ -147,20 +141,6 @@ private List<SDecl> parseSimpleDecls(final JsonParser parser) throws IOException
147141
return decls;
148142
}
149143

150-
private void addMainMethod(final Assembler assembler) {
151-
final String[] classAndMethodName = IdrisToJavaNameConverter.idrisClassMethodName("{runMain_0}").split(",");
152-
assembler.createMethod(ACC_PUBLIC + ACC_STATIC, "main/Main", "main", "([Ljava/lang/String;)V", null, null,
153-
emptyList(), emptyList());
154-
assembler.methodCodeStart();
155-
assembler.aload(0);
156-
assembler.invokeMethod(INVOKESTATIC, "io/github/mmhelloworld/idrisjvm/runtime/Runtime", "setProgramArgs", "([Ljava/lang/String;)V", false);
157-
assembler.invokeMethod(INVOKESTATIC, classAndMethodName[0], classAndMethodName[1], "()Lio/github/mmhelloworld/idrisjvm/runtime/Thunk;", false);
158-
assembler.pop();
159-
assembler.asmReturn();
160-
assembler.maxStackAndLocal(-1, -1);
161-
assembler.methodCodeEnd();
162-
}
163-
164144
private File getSourceFile(final List<String> args) {
165145
String sourceFileName = args.get(0);
166146
return getAbsoluteFile(sourceFileName, getCurrentWorkingDirectory(args));

0 commit comments

Comments
 (0)