cabal: bump data-default dependency to 0.5.0.
[hs-java.git] / TestGen.hs
index 14c91f8c95df9f0456638b8bad77ae5ca9504e82..9d1bcd8caa43ae249056e1978970aee27106c8eb 100644 (file)
@@ -1,64 +1,70 @@
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}
 
+import Control.Monad.Exception
 import qualified Data.ByteString.Lazy as B
 
-import JVM.Types
 import JVM.ClassFile
 import JVM.Converter
 import JVM.Assembler
-import JVM.Generator
-import JVM.Dump
+import JVM.Builder
+import JVM.Exceptions
+import Java.ClassPath
 
-initNT :: NameType Method
-initNT = NameType "<init>" $ MethodSignature [] ReturnsVoid
+import qualified Java.Lang
+import qualified Java.IO
 
-helloNT :: NameType Method
-helloNT = NameType "hello" $ MethodSignature [IntType] ReturnsVoid
+test :: (Throws ENotFound e, Throws ENotLoaded e, Throws UnexpectedEndMethod e) => GenerateIO e ()
+test = do
+  withClassPath $ do
+      -- Add current directory (with Hello.class) to ClassPath
+      addDirectory "."
 
-printlnNT :: NameType Method
-printlnNT = NameType "println" $ MethodSignature [ObjectType "java/lang/String"] ReturnsVoid
+  -- Load method signature: Hello.hello() from Hello.class
+  helloJava <- getClassMethod "./Hello" "hello"
 
-outNT :: NameType Field
-outNT = NameType "out" $ ObjectType "java/io/PrintStream"
+  -- Initializer method. Just calls java.lang.Object.<init>
+  newMethod [ACC_PUBLIC] "<init>" [] ReturnsVoid $ do
+      setStackSize 1
 
-valueOfNT :: NameType Method
-valueOfNT = NameType "valueOf" $ MethodSignature [IntType] (Returns $ ObjectType "java/lang/Integer")
+      aload_ I0
+      invokeSpecial Java.Lang.object Java.Lang.objectInit
+      i0 RETURN
 
-printfNT :: NameType Method
-printfNT = NameType "printf" $ MethodSignature [ObjectType "java/lang/String",
-                                                Array Nothing $ ObjectType "java/lang/Object"] (Returns $ ObjectType "java/io/PrintStream")
+  -- Declare hello() method and bind it's signature to hello.
+  hello <- newMethod [ACC_PUBLIC, ACC_STATIC] "hello" [IntType] ReturnsVoid $ do
+      setStackSize 8
 
-test :: Generate ()
-test = do
-  newMethod [ACC_PUBLIC] "<init>" [] ReturnsVoid $ do
-      i0 $ ALOAD_ I0
-      i1 INVOKESPECIAL (CMethod "java/lang/Object" initNT)
+      getStaticField Java.Lang.system Java.IO.out
+      loadString "Здравствуй, мир!"
+      invokeVirtual Java.IO.printStream Java.IO.println
+      getStaticField Java.Lang.system Java.IO.out
+      loadString "Argument: %d\n"
+      iconst_1
+      allocArray Java.Lang.object
+      dup
+      iconst_0
+      iload_ I0
+      invokeStatic Java.Lang.integer Java.Lang.valueOfInteger
+      aastore
+      invokeVirtual Java.IO.printStream Java.IO.printf
+      -- Call Hello.hello()
+      invokeStatic "Hello" helloJava
+      pop
       i0 RETURN
 
-  newMethod [ACC_PUBLIC, ACC_STATIC] "main" [Array Nothing $ ObjectType "java/lang/String"] ReturnsVoid $ do
-      i0 ICONST_5
-      i1 INVOKESTATIC (CMethod "Test" helloNT)
-      i0 RETURN
+  -- Main class method. 
+  newMethod [ACC_PUBLIC, ACC_STATIC] "main" [arrayOf Java.Lang.stringClass] ReturnsVoid $ do
+      setStackSize 1
 
-  newMethod [ACC_PUBLIC, ACC_STATIC] "hello" [IntType] ReturnsVoid $ do
-      i1 GETSTATIC (CField "java/lang/System" outNT)
-      i8 LDC1 (CString "Здравствуй, мир!")
-      i1 INVOKEVIRTUAL (CMethod "java/io/PrintStream" printlnNT)
-      i1 GETSTATIC (CField "java/lang/System" outNT)
-      i8 LDC1 (CString "Argument: %d\n")
-      i0 ICONST_1
-      i1 ANEWARRAY (CClass "java/lang/Object")
-      i0 DUP
-      i0 ICONST_0
-      i0 (ILOAD_ I0)
-      i1 INVOKESTATIC (CMethod "java/lang/Integer" valueOfNT)
-      i0 AASTORE
-      i1 INVOKEVIRTUAL (CMethod "java/io/PrintStream" printfNT)
-      i0 POP
+      iconst_5
+      -- Call previously declared method
+      invokeStatic "Test" hello
       i0 RETURN
 
-testClass = generate "Test" test
+  return ()
 
+main :: IO ()
 main = do
+  testClass <- generateIO [] "Test" test
   B.writeFile "Test.class" (encodeClass testClass)