-{-# 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)