first commit
This commit is contained in:
commit
063194f8be
349 changed files with 36508 additions and 0 deletions
0
.j
Normal file
0
.j
Normal file
BIN
AbsJavalette.hi
Normal file
BIN
AbsJavalette.hi
Normal file
Binary file not shown.
87
AbsJavalette.hs
Normal file
87
AbsJavalette.hs
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
module AbsJavalette where
|
||||||
|
|
||||||
|
-- Haskell module generated by the BNF converter
|
||||||
|
|
||||||
|
newtype Ident = Ident String deriving (Eq,Ord,Show)
|
||||||
|
data Program =
|
||||||
|
Program [TopDef]
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data TopDef =
|
||||||
|
FnDef Type Ident [Arg] Block
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Arg =
|
||||||
|
Arg Type Ident
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Block =
|
||||||
|
Block [Stmt]
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Stmt =
|
||||||
|
Empty
|
||||||
|
| BStmt Block
|
||||||
|
| Decl Type [Item]
|
||||||
|
| Ass Ident Expr
|
||||||
|
| Incr Ident
|
||||||
|
| Decr Ident
|
||||||
|
| Ret Expr
|
||||||
|
| VRet
|
||||||
|
| Cond Expr Stmt
|
||||||
|
| CondElse Expr Stmt Stmt
|
||||||
|
| While Expr Stmt
|
||||||
|
| SExp Expr
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Item =
|
||||||
|
NoInit Ident
|
||||||
|
| Init Ident Expr
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Type =
|
||||||
|
Int
|
||||||
|
| Doub
|
||||||
|
| Bool
|
||||||
|
| Void
|
||||||
|
| Fun Type [Type]
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Expr =
|
||||||
|
EVar Ident
|
||||||
|
| ELitInt Integer
|
||||||
|
| ELitDoub Double
|
||||||
|
| ELitTrue
|
||||||
|
| ELitFalse
|
||||||
|
| EApp Ident [Expr]
|
||||||
|
| EString String
|
||||||
|
| Neg Expr
|
||||||
|
| Not Expr
|
||||||
|
| EMul Expr MulOp Expr
|
||||||
|
| EAdd Expr AddOp Expr
|
||||||
|
| ERel Expr RelOp Expr
|
||||||
|
| EAnd Expr Expr
|
||||||
|
| EOr Expr Expr
|
||||||
|
| TAnot Type Expr
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data AddOp =
|
||||||
|
Plus
|
||||||
|
| Minus
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data MulOp =
|
||||||
|
Times
|
||||||
|
| Div
|
||||||
|
| Mod
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data RelOp =
|
||||||
|
LTH
|
||||||
|
| LE
|
||||||
|
| GTH
|
||||||
|
| GE
|
||||||
|
| EQU
|
||||||
|
| NE
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
86
AbsJavalette.hs.bak
Normal file
86
AbsJavalette.hs.bak
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
module AbsJavalette where
|
||||||
|
|
||||||
|
-- Haskell module generated by the BNF converter
|
||||||
|
|
||||||
|
newtype Ident = Ident String deriving (Eq,Ord,Show)
|
||||||
|
data Program =
|
||||||
|
Program [TopDef]
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data TopDef =
|
||||||
|
FnDef Type Ident [Arg] Block
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Arg =
|
||||||
|
Arg Type Ident
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Block =
|
||||||
|
Block [Stmt]
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Stmt =
|
||||||
|
Empty
|
||||||
|
| BStmt Block
|
||||||
|
| Decl Type [Item]
|
||||||
|
| Ass Ident Expr
|
||||||
|
| Incr Ident
|
||||||
|
| Decr Ident
|
||||||
|
| Ret Expr
|
||||||
|
| VRet
|
||||||
|
| Cond Expr Stmt
|
||||||
|
| CondElse Expr Stmt Stmt
|
||||||
|
| While Expr Stmt
|
||||||
|
| SExp Expr
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Item =
|
||||||
|
NoInit Ident
|
||||||
|
| Init Ident Expr
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Type =
|
||||||
|
Int
|
||||||
|
| Doub
|
||||||
|
| Bool
|
||||||
|
| Void
|
||||||
|
| Fun Type [Type]
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data Expr =
|
||||||
|
EVar Ident
|
||||||
|
| ELitInt Integer
|
||||||
|
| ELitDoub Double
|
||||||
|
| ELitTrue
|
||||||
|
| ELitFalse
|
||||||
|
| EApp Ident [Expr]
|
||||||
|
| EString String
|
||||||
|
| Neg Expr
|
||||||
|
| Not Expr
|
||||||
|
| EMul Expr MulOp Expr
|
||||||
|
| EAdd Expr AddOp Expr
|
||||||
|
| ERel Expr RelOp Expr
|
||||||
|
| EAnd Expr Expr
|
||||||
|
| EOr Expr Expr
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data AddOp =
|
||||||
|
Plus
|
||||||
|
| Minus
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data MulOp =
|
||||||
|
Times
|
||||||
|
| Div
|
||||||
|
| Mod
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
|
data RelOp =
|
||||||
|
LTH
|
||||||
|
| LE
|
||||||
|
| GTH
|
||||||
|
| GE
|
||||||
|
| EQU
|
||||||
|
| NE
|
||||||
|
deriving (Eq,Ord,Show)
|
||||||
|
|
BIN
AbsJavalette.o
Normal file
BIN
AbsJavalette.o
Normal file
Binary file not shown.
BIN
Compiler.hi
Normal file
BIN
Compiler.hi
Normal file
Binary file not shown.
195
Compiler.hs
Normal file
195
Compiler.hs
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
module Compiler where
|
||||||
|
|
||||||
|
import Debug.Trace
|
||||||
|
import AbsJavalette
|
||||||
|
import PrintJavalette
|
||||||
|
import ErrM
|
||||||
|
import Control.Monad.State
|
||||||
|
import Data.List
|
||||||
|
|
||||||
|
type Variables = [[(Ident, Int)]]
|
||||||
|
-- vars, stackCount, localCount, labelCount, finalCode, tempCode, classname
|
||||||
|
type MyState = (Variables, Int, Int, Int, String, String, String)
|
||||||
|
type MyStateM = State MyState
|
||||||
|
|
||||||
|
|
||||||
|
compile :: Program -> String -> String
|
||||||
|
compile (Program fs) classname =
|
||||||
|
do let code = evalState (compileProgram fs >> getFinalCode) (emptyState classname)
|
||||||
|
boilerPlate classname code
|
||||||
|
|
||||||
|
-- initializing functions
|
||||||
|
emptyState :: String -> MyState
|
||||||
|
emptyState classname = ([[]], 0, 0, "", "", classname)
|
||||||
|
|
||||||
|
boilerPlate :: String -> String -> String
|
||||||
|
boilerPlate classname code =
|
||||||
|
".class public " ++ classname ++ "\n" ++
|
||||||
|
".super java/lang/Object\n" ++
|
||||||
|
".method public <init>()V\n" ++
|
||||||
|
" aload_0\n" ++
|
||||||
|
" invokespecial java/lang/Object/<init>()V\n" ++
|
||||||
|
" return\n" ++
|
||||||
|
".end method\n\n" ++
|
||||||
|
".method public static main([Ljava/lang/String;)V\n" ++
|
||||||
|
" .limit locals 1\n" ++
|
||||||
|
" invokestatic " ++ classname ++ "/main()I\n" ++
|
||||||
|
" pop\n" ++
|
||||||
|
" return\n" ++
|
||||||
|
".end method\n\n" ++
|
||||||
|
code
|
||||||
|
|
||||||
|
|
||||||
|
compileProgram :: [TopDef] -> MyStateM ()
|
||||||
|
compileProgram [] = return ()
|
||||||
|
compileProgram (f:fs) =
|
||||||
|
do compileFunc f
|
||||||
|
compileProgram fs
|
||||||
|
return ()
|
||||||
|
|
||||||
|
compileFunc :: TopDef -> MyStateM ()
|
||||||
|
compileFunc f@(FnDef t (Ident i) a (Block s)) =
|
||||||
|
do compileStmts s
|
||||||
|
addFinalCode f
|
||||||
|
return ()
|
||||||
|
|
||||||
|
|
||||||
|
compileStmts :: [Stmt] -> MyStateM ()
|
||||||
|
compileStmts [] = return ()
|
||||||
|
compileStmts (s:ss) = do compileStmt s
|
||||||
|
compileStmts ss
|
||||||
|
|
||||||
|
compileStmt :: Stmt -> MyStateM ()
|
||||||
|
compileStmt s = case s of
|
||||||
|
SExp e -> do compileExpr e
|
||||||
|
return ()
|
||||||
|
Ret e -> do compileExpr e
|
||||||
|
return ()
|
||||||
|
VRet -> do addTempCode (" return\n")
|
||||||
|
return ()
|
||||||
|
Cond e stm -> do compileExpr e
|
||||||
|
addTempCode (" ")
|
||||||
|
return ()
|
||||||
|
_ -> return ()
|
||||||
|
|
||||||
|
compileExpr :: Expr -> MyStateM ()
|
||||||
|
compileExpr expr = case expr of
|
||||||
|
TAnot t (EApp (Ident i) exs) -> do ts <- compileList exs []
|
||||||
|
let tss = intercalate "," (map (\a -> jType a) ts)
|
||||||
|
ci <- getClassIdent i
|
||||||
|
addTempCode (" invokestatic " ++ ci ++ "(" ++ tss ++ ")" ++ (jType t) ++ "\n")
|
||||||
|
addStackCount 1
|
||||||
|
return ()
|
||||||
|
EApp (Ident "printString") a -> do let EString s = head a
|
||||||
|
addTempCode (" ldc " ++ show s ++ "\n")
|
||||||
|
addTempCode (" invokestatic Runtime/printString(Ljava/lang/String;)V\n")
|
||||||
|
return ()
|
||||||
|
TAnot t (ELitInt i) -> do case and [i >= 0, i <= 5] of
|
||||||
|
True -> addTempCode (" iconst_" ++ show i ++ "\n")
|
||||||
|
False -> case i == -1 of
|
||||||
|
True -> addTempCode (" iconst_m1")
|
||||||
|
False -> case and [i >= -128, i <= 127] of
|
||||||
|
True -> addTempCode (" bipush " ++ show i ++ "\n")
|
||||||
|
False -> addTempCode (" sipush " ++ show i ++ "\n")
|
||||||
|
addStackCount 1
|
||||||
|
return ()
|
||||||
|
TAnot t (EMul e1 op e2) -> do compileExpr e1
|
||||||
|
compileExpr e2
|
||||||
|
let ts = case t of
|
||||||
|
Int -> "i"
|
||||||
|
Doub -> "d"
|
||||||
|
case op of
|
||||||
|
Times -> addTempCode (" " ++ ts ++ "mul\n")
|
||||||
|
Div -> addTempCode (" " ++ ts ++ "div\n")
|
||||||
|
Mod -> addTempCode (" " ++ ts ++ "rem\n")
|
||||||
|
|
||||||
|
TAnot t (EAdd e1 op e2) -> do compileExpr e1
|
||||||
|
compileExpr e2
|
||||||
|
let ts = case t of
|
||||||
|
Int -> "i"
|
||||||
|
Doub -> "d"
|
||||||
|
case op of
|
||||||
|
Plus -> addTempCode (" " ++ ts ++ "add\n")
|
||||||
|
Minus -> addTempCode (" " ++ ts ++ "sub\n")
|
||||||
|
return ()
|
||||||
|
TAnot t (ELitDoub d) -> do case d of
|
||||||
|
0.0 -> addTempCode (" dconst_0\n")
|
||||||
|
1.0 -> addTempCode (" dconst_1\n")
|
||||||
|
_ -> addTempCode (" ldc2_w " ++ show d ++ "\n")
|
||||||
|
addStackCount 2
|
||||||
|
return ()
|
||||||
|
TAnot t (Neg e) -> do compileExpr e
|
||||||
|
case t of
|
||||||
|
Int -> addTempCode " ineg\n"
|
||||||
|
Doub -> addTempCode " dneg\n"
|
||||||
|
|
||||||
|
e -> do addTempCode (" ; " ++ (show e) ++ "\n")
|
||||||
|
return ()
|
||||||
|
|
||||||
|
compileList :: [Expr] -> [Type] -> MyStateM ([Type])
|
||||||
|
compileList [] ts = return (ts)
|
||||||
|
compileList (e2@(TAnot t e):es) ts = do compileExpr e2
|
||||||
|
(compileList es (ts ++ [t]))
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Helper functions
|
||||||
|
getFinalCode :: MyStateM (String)
|
||||||
|
getFinalCode = do (vars, stackCount, localCount, labelCount, final, temp, classname) <- get
|
||||||
|
return final
|
||||||
|
|
||||||
|
addFinalCode :: TopDef -> MyStateM ()
|
||||||
|
addFinalCode (FnDef t (Ident i) a (Block s)) =
|
||||||
|
do let p = intercalate "," (map (\(Arg t i) -> jType t) a)
|
||||||
|
let rt = case t of
|
||||||
|
Bool -> " ireturn\n"
|
||||||
|
Int -> " ireturn\n"
|
||||||
|
Doub -> " dreturn\n"
|
||||||
|
Void -> " return\n"
|
||||||
|
(vars, stackCount, localCount, labelCount, final, temp, classname) <- get
|
||||||
|
let newFinal = final ++
|
||||||
|
".method public static " ++ i ++ "(" ++ p ++ ")" ++ jType t ++ "\n" ++
|
||||||
|
" .limit locals " ++ show localCount ++ "\n" ++
|
||||||
|
" .limit stack " ++ show stackCount ++ "\n" ++
|
||||||
|
temp ++
|
||||||
|
rt ++
|
||||||
|
".end method\n\n"
|
||||||
|
put ([], 0, 0, labelCount, newFinal, "", classname) -- state
|
||||||
|
return ()
|
||||||
|
|
||||||
|
jType :: Type -> String
|
||||||
|
jType t = case t of
|
||||||
|
Int -> "I"
|
||||||
|
Doub -> "D"
|
||||||
|
Bool -> "B"
|
||||||
|
Void -> "V"
|
||||||
|
|
||||||
|
|
||||||
|
addTempCode :: String -> MyStateM ()
|
||||||
|
addTempCode s = do (vars, stackCount, localCount, labelCount, final, temp, classname) <- get
|
||||||
|
let newTemp = temp ++ s
|
||||||
|
put (vars, stackCount, localCount, labelCount, final, newTemp, classname) -- state
|
||||||
|
return ()
|
||||||
|
|
||||||
|
addStackCount :: Int -> MyStateM ()
|
||||||
|
addStackCount i =
|
||||||
|
do (vars, stackCount, localCount, labelCount, final, temp, classname) <- get
|
||||||
|
put (vars, stackCount + i, localCount, labelCount, final, temp, classname) -- state
|
||||||
|
return ()
|
||||||
|
|
||||||
|
getClassName :: MyStateM (String)
|
||||||
|
getClassName = do (vars, stackCount, localCount, labelCount, final, temp, classname) <- get
|
||||||
|
return classname
|
||||||
|
|
||||||
|
incLabelCount :: MaStateM (Int)
|
||||||
|
incLabelCount = do (vars, stackCount, localCount, labelCount, final, temp, classname) <- get
|
||||||
|
put (vars, stackCount, localCount, labelCount + 1, final, temp, classname)
|
||||||
|
return labelCount
|
||||||
|
|
||||||
|
getClassIdent :: String -> MyStateM (String)
|
||||||
|
getClassIdent i =
|
||||||
|
case find (== i) ["printString", "printDouble", "printInt", "readDouble", "readInt"] of
|
||||||
|
Just _ -> return ("Runtime/" ++ i)
|
||||||
|
Nothing -> do classname <- getClassName
|
||||||
|
return (classname ++ "/" ++ i)
|
||||||
|
|
||||||
|
|
BIN
Compiler.o
Normal file
BIN
Compiler.o
Normal file
Binary file not shown.
1
DocJavalette.aux
Normal file
1
DocJavalette.aux
Normal file
|
@ -0,0 +1 @@
|
||||||
|
\relax
|
BIN
DocJavalette.dvi
Normal file
BIN
DocJavalette.dvi
Normal file
Binary file not shown.
215
DocJavalette.log
Normal file
215
DocJavalette.log
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) (format=latex 2010.8.12) 19 APR 2011 11:09
|
||||||
|
entering extended mode
|
||||||
|
**DocJavalette.tex
|
||||||
|
(./DocJavalette.tex
|
||||||
|
LaTeX2e <2003/12/01>
|
||||||
|
Babel <v3.8d> and hyphenation patterns for american, french, german, ngerman, b
|
||||||
|
ahasa, basque, bulgarian, catalan, croatian, czech, danish, dutch, esperanto, e
|
||||||
|
stonian, finnish, greek, icelandic, irish, italian, latin, magyar, norsk, polis
|
||||||
|
h, portuges, romanian, russian, serbian, slovak, slovene, spanish, swedish, tur
|
||||||
|
kish, ukrainian, nohyphenation, loaded.
|
||||||
|
|
||||||
|
(/usr/share/texmf/tex/latex/base/article.cls
|
||||||
|
Document Class: article 2004/02/16 v1.4f Standard LaTeX document class
|
||||||
|
(/usr/share/texmf/tex/latex/base/size11.clo
|
||||||
|
File: size11.clo 2004/02/16 v1.4f Standard LaTeX file (size option)
|
||||||
|
)
|
||||||
|
\c@part=\count79
|
||||||
|
\c@section=\count80
|
||||||
|
\c@subsection=\count81
|
||||||
|
\c@subsubsection=\count82
|
||||||
|
\c@paragraph=\count83
|
||||||
|
\c@subparagraph=\count84
|
||||||
|
\c@figure=\count85
|
||||||
|
\c@table=\count86
|
||||||
|
\abovecaptionskip=\skip41
|
||||||
|
\belowcaptionskip=\skip42
|
||||||
|
\bibindent=\dimen102
|
||||||
|
) (./DocJavalette.aux)
|
||||||
|
\openout1 = `DocJavalette.aux'.
|
||||||
|
|
||||||
|
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 9.
|
||||||
|
LaTeX Font Info: ... okay on input line 9.
|
||||||
|
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 9.
|
||||||
|
LaTeX Font Info: ... okay on input line 9.
|
||||||
|
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 9.
|
||||||
|
LaTeX Font Info: ... okay on input line 9.
|
||||||
|
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 9.
|
||||||
|
LaTeX Font Info: ... okay on input line 9.
|
||||||
|
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 9.
|
||||||
|
LaTeX Font Info: ... okay on input line 9.
|
||||||
|
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 9.
|
||||||
|
LaTeX Font Info: ... okay on input line 9.
|
||||||
|
LaTeX Font Info: External font `cmex10' loaded for size
|
||||||
|
(Font) <12> on input line 11.
|
||||||
|
LaTeX Font Info: External font `cmex10' loaded for size
|
||||||
|
(Font) <8> on input line 11.
|
||||||
|
LaTeX Font Info: External font `cmex10' loaded for size
|
||||||
|
(Font) <6> on input line 11.
|
||||||
|
LaTeX Font Info: External font `cmex10' loaded for size
|
||||||
|
(Font) <10.95> on input line 26.
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 51--52
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 53--59
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
[1
|
||||||
|
|
||||||
|
]
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 60--61
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
LaTeX Font Info: Try loading font information for OMS+cmtt on input line 64.
|
||||||
|
|
||||||
|
LaTeX Font Info: No file OMScmtt.fd. on input line 64.
|
||||||
|
|
||||||
|
LaTeX Font Warning: Font shape `OMS/cmtt/m/n' undefined
|
||||||
|
(Font) using `OMS/cmsy/m/n' instead
|
||||||
|
(Font) for symbol `textbraceleft' on input line 64.
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 62--72
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 77--81
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 82--85
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 86--89
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 90--94
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 95--98
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 99--104
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 105--108
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 109--113
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
[2]
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 114--128
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 129--133
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 134--138
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 139--145
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 146--151
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 152--162
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 163--168
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 169--173
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 174--178
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
[3]
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 179--183
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 184--188
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 189--193
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 194--199
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 200--204
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 205--210
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
Underfull \hbox (badness 10000) in paragraph at lines 211--219
|
||||||
|
|
||||||
|
[]
|
||||||
|
|
||||||
|
[4] (./DocJavalette.aux)
|
||||||
|
|
||||||
|
LaTeX Font Warning: Some font shapes were not available, defaults substituted.
|
||||||
|
|
||||||
|
)
|
||||||
|
Here is how much of TeX's memory you used:
|
||||||
|
252 strings out of 94501
|
||||||
|
2714 string characters out of 1176789
|
||||||
|
56348 words of memory out of 1000000
|
||||||
|
3492 multiletter control sequences out of 10000+50000
|
||||||
|
9370 words of font info for 33 fonts, out of 500000 for 2000
|
||||||
|
580 hyphenation exceptions out of 1000
|
||||||
|
21i,9n,19p,381b,185s stack positions out of 1500i,500n,5000p,200000b,5000s
|
||||||
|
|
||||||
|
Output written on DocJavalette.dvi (4 pages, 8352 bytes).
|
2067
DocJavalette.ps
Normal file
2067
DocJavalette.ps
Normal file
File diff suppressed because it is too large
Load diff
223
DocJavalette.tex
Normal file
223
DocJavalette.tex
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
\batchmode
|
||||||
|
%This Latex file is machine-generated by the BNF-converter
|
||||||
|
|
||||||
|
\documentclass[a4paper,11pt]{article}
|
||||||
|
\author{BNF-converter}
|
||||||
|
\title{The Language Javalette}
|
||||||
|
\setlength{\parindent}{0mm}
|
||||||
|
\setlength{\parskip}{1mm}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
\newcommand{\emptyP}{\mbox{$\epsilon$}}
|
||||||
|
\newcommand{\terminal}[1]{\mbox{{\texttt {#1}}}}
|
||||||
|
\newcommand{\nonterminal}[1]{\mbox{$\langle \mbox{{\sl #1 }} \! \rangle$}}
|
||||||
|
\newcommand{\arrow}{\mbox{::=}}
|
||||||
|
\newcommand{\delimit}{\mbox{$|$}}
|
||||||
|
\newcommand{\reserved}[1]{\mbox{{\texttt {#1}}}}
|
||||||
|
\newcommand{\literal}[1]{\mbox{{\texttt {#1}}}}
|
||||||
|
\newcommand{\symb}[1]{\mbox{{\texttt {#1}}}}
|
||||||
|
|
||||||
|
This document was automatically generated by the {\em BNF-Converter}. It was generated together with the lexer, the parser, and the abstract syntax module, which guarantees that the document matches with the implementation of the language (provided no hand-hacking has taken place).
|
||||||
|
|
||||||
|
\section*{The lexical structure of Javalette}
|
||||||
|
\subsection*{Identifiers}
|
||||||
|
Identifiers \nonterminal{Ident} are unquoted strings beginning with a letter,
|
||||||
|
followed by any combination of letters, digits, and the characters {\tt \_ '},
|
||||||
|
reserved words excluded.
|
||||||
|
|
||||||
|
|
||||||
|
\subsection*{Literals}
|
||||||
|
Integer literals \nonterminal{Int}\ are nonempty sequences of digits.
|
||||||
|
|
||||||
|
|
||||||
|
Double-precision float literals \nonterminal{Double}\ have the structure
|
||||||
|
indicated by the regular expression $\nonterminal{digit}+ \mbox{{\it `.'}} \nonterminal{digit}+ (\mbox{{\it `e'}} \mbox{{\it `-'}}? \nonterminal{digit}+)?$ i.e.\
|
||||||
|
two sequences of digits separated by a decimal point, optionally
|
||||||
|
followed by an unsigned or negative exponent.
|
||||||
|
|
||||||
|
|
||||||
|
String literals \nonterminal{String}\ have the form
|
||||||
|
\terminal{"}$x$\terminal{"}, where $x$ is any sequence of any characters
|
||||||
|
except \terminal{"}\ unless preceded by \verb6\6.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\subsection*{Reserved words and symbols}
|
||||||
|
The set of reserved words is the set of terminals appearing in the grammar. Those reserved words that consist of non-letter characters are called symbols, and they are treated in a different way from those that are similar to identifiers. The lexer follows rules familiar from languages like Haskell, C, and Java, including longest match and spacing conventions.
|
||||||
|
|
||||||
|
The reserved words used in Javalette are the following: \\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\reserved{boolean}} &{\reserved{double}} &{\reserved{else}} \\
|
||||||
|
{\reserved{false}} &{\reserved{if}} &{\reserved{int}} \\
|
||||||
|
{\reserved{return}} &{\reserved{true}} &{\reserved{void}} \\
|
||||||
|
{\reserved{while}} & & \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
The symbols used in Javalette are the following: \\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\symb{(}} &{\symb{)}} &{\symb{,}} \\
|
||||||
|
{\symb{\{}} &{\symb{\}}} &{\symb{;}} \\
|
||||||
|
{\symb{{$=$}}} &{\symb{{$+$}{$+$}}} &{\symb{{$-$}{$-$}}} \\
|
||||||
|
{\symb{{$-$}}} &{\symb{!}} &{\symb{\&\&}} \\
|
||||||
|
{\symb{{$|$}{$|$}}} &{\symb{{$<$}}} &{\symb{{$>$}}} \\
|
||||||
|
{\symb{{$+$}}} &{\symb{*}} &{\symb{/}} \\
|
||||||
|
{\symb{\%}} &{\symb{{$<$}{$=$}}} &{\symb{{$>$}{$=$}}} \\
|
||||||
|
{\symb{{$=$}{$=$}}} &{\symb{!{$=$}}} & \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\subsection*{Comments}
|
||||||
|
Single-line comments begin with {\symb{\#}}, {\symb{//}}. \\Multiple-line comments are enclosed with {\symb{/*}} and {\symb{*/}}.
|
||||||
|
|
||||||
|
\section*{The syntactic structure of Javalette}
|
||||||
|
Non-terminals are enclosed between $\langle$ and $\rangle$.
|
||||||
|
The symbols {\arrow} (production), {\delimit} (union)
|
||||||
|
and {\emptyP} (empty rule) belong to the BNF notation.
|
||||||
|
All other symbols are terminals.\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Program}} & {\arrow} &{\nonterminal{ListTopDef}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{TopDef}} & {\arrow} &{\nonterminal{Type}} {\nonterminal{Ident}} {\terminal{(}} {\nonterminal{ListArg}} {\terminal{)}} {\nonterminal{Block}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListTopDef}} & {\arrow} &{\nonterminal{TopDef}} \\
|
||||||
|
& {\delimit} &{\nonterminal{TopDef}} {\nonterminal{ListTopDef}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Arg}} & {\arrow} &{\nonterminal{Type}} {\nonterminal{Ident}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListArg}} & {\arrow} &{\emptyP} \\
|
||||||
|
& {\delimit} &{\nonterminal{Arg}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Arg}} {\terminal{,}} {\nonterminal{ListArg}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Block}} & {\arrow} &{\terminal{\{}} {\nonterminal{ListStmt}} {\terminal{\}}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListStmt}} & {\arrow} &{\emptyP} \\
|
||||||
|
& {\delimit} &{\nonterminal{Stmt}} {\nonterminal{ListStmt}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Stmt}} & {\arrow} &{\terminal{;}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Block}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Type}} {\nonterminal{ListItem}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{{$=$}}} {\nonterminal{Expr}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{{$+$}{$+$}}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{{$-$}{$-$}}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\terminal{return}} {\nonterminal{Expr}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\terminal{return}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\terminal{if}} {\terminal{(}} {\nonterminal{Expr}} {\terminal{)}} {\nonterminal{Stmt}} \\
|
||||||
|
& {\delimit} &{\terminal{if}} {\terminal{(}} {\nonterminal{Expr}} {\terminal{)}} {\nonterminal{Stmt}} {\terminal{else}} {\nonterminal{Stmt}} \\
|
||||||
|
& {\delimit} &{\terminal{while}} {\terminal{(}} {\nonterminal{Expr}} {\terminal{)}} {\nonterminal{Stmt}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr}} {\terminal{;}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Item}} & {\arrow} &{\nonterminal{Ident}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{{$=$}}} {\nonterminal{Expr}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListItem}} & {\arrow} &{\nonterminal{Item}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Item}} {\terminal{,}} {\nonterminal{ListItem}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Type}} & {\arrow} &{\terminal{int}} \\
|
||||||
|
& {\delimit} &{\terminal{double}} \\
|
||||||
|
& {\delimit} &{\terminal{boolean}} \\
|
||||||
|
& {\delimit} &{\terminal{void}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListType}} & {\arrow} &{\emptyP} \\
|
||||||
|
& {\delimit} &{\nonterminal{Type}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Type}} {\terminal{,}} {\nonterminal{ListType}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr6}} & {\arrow} &{\nonterminal{Ident}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Integer}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Double}} \\
|
||||||
|
& {\delimit} &{\terminal{true}} \\
|
||||||
|
& {\delimit} &{\terminal{false}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{(}} {\nonterminal{ListExpr}} {\terminal{)}} \\
|
||||||
|
& {\delimit} &{\nonterminal{String}} \\
|
||||||
|
& {\delimit} &{\terminal{(}} {\nonterminal{Expr}} {\terminal{)}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr5}} & {\arrow} &{\terminal{{$-$}}} {\nonterminal{Expr6}} \\
|
||||||
|
& {\delimit} &{\terminal{!}} {\nonterminal{Expr6}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr6}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr4}} & {\arrow} &{\nonterminal{Expr4}} {\nonterminal{MulOp}} {\nonterminal{Expr5}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr5}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr3}} & {\arrow} &{\nonterminal{Expr3}} {\nonterminal{AddOp}} {\nonterminal{Expr4}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr4}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr2}} & {\arrow} &{\nonterminal{Expr2}} {\nonterminal{RelOp}} {\nonterminal{Expr3}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr3}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr1}} & {\arrow} &{\nonterminal{Expr2}} {\terminal{\&\&}} {\nonterminal{Expr1}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr2}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr}} & {\arrow} &{\nonterminal{Expr1}} {\terminal{{$|$}{$|$}}} {\nonterminal{Expr}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr1}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListExpr}} & {\arrow} &{\emptyP} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr}} {\terminal{,}} {\nonterminal{ListExpr}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{AddOp}} & {\arrow} &{\terminal{{$+$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$-$}}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{MulOp}} & {\arrow} &{\terminal{*}} \\
|
||||||
|
& {\delimit} &{\terminal{/}} \\
|
||||||
|
& {\delimit} &{\terminal{\%}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{RelOp}} & {\arrow} &{\terminal{{$<$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$<$}{$=$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$>$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$>$}{$=$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$=$}{$=$}}} \\
|
||||||
|
& {\delimit} &{\terminal{!{$=$}}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\end{document}
|
||||||
|
|
223
DocJavalette.tex.bak
Normal file
223
DocJavalette.tex.bak
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
\batchmode
|
||||||
|
%This Latex file is machine-generated by the BNF-converter
|
||||||
|
|
||||||
|
\documentclass[a4paper,11pt]{article}
|
||||||
|
\author{BNF-converter}
|
||||||
|
\title{The Language Javalette}
|
||||||
|
\setlength{\parindent}{0mm}
|
||||||
|
\setlength{\parskip}{1mm}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
\newcommand{\emptyP}{\mbox{$\epsilon$}}
|
||||||
|
\newcommand{\terminal}[1]{\mbox{{\texttt {#1}}}}
|
||||||
|
\newcommand{\nonterminal}[1]{\mbox{$\langle \mbox{{\sl #1 }} \! \rangle$}}
|
||||||
|
\newcommand{\arrow}{\mbox{::=}}
|
||||||
|
\newcommand{\delimit}{\mbox{$|$}}
|
||||||
|
\newcommand{\reserved}[1]{\mbox{{\texttt {#1}}}}
|
||||||
|
\newcommand{\literal}[1]{\mbox{{\texttt {#1}}}}
|
||||||
|
\newcommand{\symb}[1]{\mbox{{\texttt {#1}}}}
|
||||||
|
|
||||||
|
This document was automatically generated by the {\em BNF-Converter}. It was generated together with the lexer, the parser, and the abstract syntax module, which guarantees that the document matches with the implementation of the language (provided no hand-hacking has taken place).
|
||||||
|
|
||||||
|
\section*{The lexical structure of Javalette}
|
||||||
|
\subsection*{Identifiers}
|
||||||
|
Identifiers \nonterminal{Ident} are unquoted strings beginning with a letter,
|
||||||
|
followed by any combination of letters, digits, and the characters {\tt \_ '},
|
||||||
|
reserved words excluded.
|
||||||
|
|
||||||
|
|
||||||
|
\subsection*{Literals}
|
||||||
|
Integer literals \nonterminal{Int}\ are nonempty sequences of digits.
|
||||||
|
|
||||||
|
|
||||||
|
Double-precision float literals \nonterminal{Double}\ have the structure
|
||||||
|
indicated by the regular expression $\nonterminal{digit}+ \mbox{{\it `.'}} \nonterminal{digit}+ (\mbox{{\it `e'}} \mbox{{\it `-'}}? \nonterminal{digit}+)?$ i.e.\
|
||||||
|
two sequences of digits separated by a decimal point, optionally
|
||||||
|
followed by an unsigned or negative exponent.
|
||||||
|
|
||||||
|
|
||||||
|
String literals \nonterminal{String}\ have the form
|
||||||
|
\terminal{"}$x$\terminal{"}, where $x$ is any sequence of any characters
|
||||||
|
except \terminal{"}\ unless preceded by \verb6\6.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\subsection*{Reserved words and symbols}
|
||||||
|
The set of reserved words is the set of terminals appearing in the grammar. Those reserved words that consist of non-letter characters are called symbols, and they are treated in a different way from those that are similar to identifiers. The lexer follows rules familiar from languages like Haskell, C, and Java, including longest match and spacing conventions.
|
||||||
|
|
||||||
|
The reserved words used in Javalette are the following: \\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\reserved{boolean}} &{\reserved{double}} &{\reserved{else}} \\
|
||||||
|
{\reserved{false}} &{\reserved{if}} &{\reserved{int}} \\
|
||||||
|
{\reserved{return}} &{\reserved{true}} &{\reserved{void}} \\
|
||||||
|
{\reserved{while}} & & \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
The symbols used in Javalette are the following: \\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\symb{(}} &{\symb{)}} &{\symb{,}} \\
|
||||||
|
{\symb{\{}} &{\symb{\}}} &{\symb{;}} \\
|
||||||
|
{\symb{{$=$}}} &{\symb{{$+$}{$+$}}} &{\symb{{$-$}{$-$}}} \\
|
||||||
|
{\symb{{$-$}}} &{\symb{!}} &{\symb{\&\&}} \\
|
||||||
|
{\symb{{$|$}{$|$}}} &{\symb{{$+$}}} &{\symb{*}} \\
|
||||||
|
{\symb{/}} &{\symb{\%}} &{\symb{{$<$}}} \\
|
||||||
|
{\symb{{$<$}{$=$}}} &{\symb{{$>$}}} &{\symb{{$>$}{$=$}}} \\
|
||||||
|
{\symb{{$=$}{$=$}}} &{\symb{!{$=$}}} & \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\subsection*{Comments}
|
||||||
|
Single-line comments begin with {\symb{\#}}, {\symb{//}}. \\Multiple-line comments are enclosed with {\symb{/*}} and {\symb{*/}}.
|
||||||
|
|
||||||
|
\section*{The syntactic structure of Javalette}
|
||||||
|
Non-terminals are enclosed between $\langle$ and $\rangle$.
|
||||||
|
The symbols {\arrow} (production), {\delimit} (union)
|
||||||
|
and {\emptyP} (empty rule) belong to the BNF notation.
|
||||||
|
All other symbols are terminals.\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Program}} & {\arrow} &{\nonterminal{ListTopDef}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{TopDef}} & {\arrow} &{\nonterminal{Type}} {\nonterminal{Ident}} {\terminal{(}} {\nonterminal{ListArg}} {\terminal{)}} {\nonterminal{Block}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListTopDef}} & {\arrow} &{\nonterminal{TopDef}} \\
|
||||||
|
& {\delimit} &{\nonterminal{TopDef}} {\nonterminal{ListTopDef}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Arg}} & {\arrow} &{\nonterminal{Type}} {\nonterminal{Ident}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListArg}} & {\arrow} &{\emptyP} \\
|
||||||
|
& {\delimit} &{\nonterminal{Arg}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Arg}} {\terminal{,}} {\nonterminal{ListArg}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Block}} & {\arrow} &{\terminal{\{}} {\nonterminal{ListStmt}} {\terminal{\}}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListStmt}} & {\arrow} &{\emptyP} \\
|
||||||
|
& {\delimit} &{\nonterminal{Stmt}} {\nonterminal{ListStmt}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Stmt}} & {\arrow} &{\terminal{;}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Block}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Type}} {\nonterminal{ListItem}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{{$=$}}} {\nonterminal{Expr}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{{$+$}{$+$}}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{{$-$}{$-$}}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\terminal{return}} {\nonterminal{Expr}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\terminal{return}} {\terminal{;}} \\
|
||||||
|
& {\delimit} &{\terminal{if}} {\terminal{(}} {\nonterminal{Expr}} {\terminal{)}} {\nonterminal{Stmt}} \\
|
||||||
|
& {\delimit} &{\terminal{if}} {\terminal{(}} {\nonterminal{Expr}} {\terminal{)}} {\nonterminal{Stmt}} {\terminal{else}} {\nonterminal{Stmt}} \\
|
||||||
|
& {\delimit} &{\terminal{while}} {\terminal{(}} {\nonterminal{Expr}} {\terminal{)}} {\nonterminal{Stmt}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr}} {\terminal{;}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Item}} & {\arrow} &{\nonterminal{Ident}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{{$=$}}} {\nonterminal{Expr}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListItem}} & {\arrow} &{\nonterminal{Item}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Item}} {\terminal{,}} {\nonterminal{ListItem}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Type}} & {\arrow} &{\terminal{int}} \\
|
||||||
|
& {\delimit} &{\terminal{double}} \\
|
||||||
|
& {\delimit} &{\terminal{boolean}} \\
|
||||||
|
& {\delimit} &{\terminal{void}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListType}} & {\arrow} &{\emptyP} \\
|
||||||
|
& {\delimit} &{\nonterminal{Type}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Type}} {\terminal{,}} {\nonterminal{ListType}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr6}} & {\arrow} &{\nonterminal{Ident}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Integer}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Double}} \\
|
||||||
|
& {\delimit} &{\terminal{true}} \\
|
||||||
|
& {\delimit} &{\terminal{false}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Ident}} {\terminal{(}} {\nonterminal{ListExpr}} {\terminal{)}} \\
|
||||||
|
& {\delimit} &{\nonterminal{String}} \\
|
||||||
|
& {\delimit} &{\terminal{(}} {\nonterminal{Expr}} {\terminal{)}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr5}} & {\arrow} &{\terminal{{$-$}}} {\nonterminal{Expr6}} \\
|
||||||
|
& {\delimit} &{\terminal{!}} {\nonterminal{Expr6}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr6}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr4}} & {\arrow} &{\nonterminal{Expr4}} {\nonterminal{MulOp}} {\nonterminal{Expr5}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr5}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr3}} & {\arrow} &{\nonterminal{Expr3}} {\nonterminal{AddOp}} {\nonterminal{Expr4}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr4}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr2}} & {\arrow} &{\nonterminal{Expr2}} {\nonterminal{RelOp}} {\nonterminal{Expr3}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr3}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr1}} & {\arrow} &{\nonterminal{Expr2}} {\terminal{\&\&}} {\nonterminal{Expr1}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr2}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{Expr}} & {\arrow} &{\nonterminal{Expr1}} {\terminal{{$|$}{$|$}}} {\nonterminal{Expr}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr1}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{ListExpr}} & {\arrow} &{\emptyP} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr}} \\
|
||||||
|
& {\delimit} &{\nonterminal{Expr}} {\terminal{,}} {\nonterminal{ListExpr}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{AddOp}} & {\arrow} &{\terminal{{$+$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$-$}}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{MulOp}} & {\arrow} &{\terminal{*}} \\
|
||||||
|
& {\delimit} &{\terminal{/}} \\
|
||||||
|
& {\delimit} &{\terminal{\%}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
\begin{tabular}{lll}
|
||||||
|
{\nonterminal{RelOp}} & {\arrow} &{\terminal{{$<$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$<$}{$=$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$>$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$>$}{$=$}}} \\
|
||||||
|
& {\delimit} &{\terminal{{$=$}{$=$}}} \\
|
||||||
|
& {\delimit} &{\terminal{!{$=$}}} \\
|
||||||
|
\end{tabular}\\
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\end{document}
|
||||||
|
|
131
DocJavalette.txt
Normal file
131
DocJavalette.txt
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
The Language Javalette
|
||||||
|
BNF Converter
|
||||||
|
|
||||||
|
|
||||||
|
%This txt2tags file is machine-generated by the BNF-converter
|
||||||
|
%Process by txt2tags to generate html or latex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This document was automatically generated by the //BNF-Converter//. It was generated together with the lexer, the parser, and the abstract syntax module, which guarantees that the document matches with the implementation of the language (provided no hand-hacking has taken place).
|
||||||
|
|
||||||
|
==The lexical structure of Javalette==
|
||||||
|
===Identifiers===
|
||||||
|
Identifiers //Ident// are unquoted strings beginning with a letter,
|
||||||
|
followed by any combination of letters, digits, and the characters ``_ '``
|
||||||
|
reserved words excluded.
|
||||||
|
|
||||||
|
|
||||||
|
===Literals===
|
||||||
|
Integer literals //Integer// are nonempty sequences of digits.
|
||||||
|
|
||||||
|
|
||||||
|
Double-precision float literals //Double// have the structure
|
||||||
|
indicated by the regular expression ``digit+ '.' digit+ ('e' ('-')? digit+)?`` i.e.\
|
||||||
|
two sequences of digits separated by a decimal point, optionally
|
||||||
|
followed by an unsigned or negative exponent.
|
||||||
|
|
||||||
|
|
||||||
|
String literals //String// have the form
|
||||||
|
``"``//x//``"``}, where //x// is any sequence of any characters
|
||||||
|
except ``"`` unless preceded by ``\``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
===Reserved words and symbols===
|
||||||
|
The set of reserved words is the set of terminals appearing in the grammar. Those reserved words that consist of non-letter characters are called symbols, and they are treated in a different way from those that are similar to identifiers. The lexer follows rules familiar from languages like Haskell, C, and Java, including longest match and spacing conventions.
|
||||||
|
|
||||||
|
The reserved words used in Javalette are the following:
|
||||||
|
| ``boolean`` | ``double`` | ``else`` | ``false``
|
||||||
|
| ``if`` | ``int`` | ``return`` | ``true``
|
||||||
|
| ``void`` | ``while`` | |
|
||||||
|
|
||||||
|
The symbols used in Javalette are the following:
|
||||||
|
| ( | ) | , | {
|
||||||
|
| } | ; | = | ++
|
||||||
|
| -- | - | ! | &&
|
||||||
|
| || | < | > | +
|
||||||
|
| * | / | % | <=
|
||||||
|
| >= | == | != |
|
||||||
|
|
||||||
|
===Comments===
|
||||||
|
Single-line comments begin with #, //.Multiple-line comments are enclosed with /* and */.
|
||||||
|
|
||||||
|
==The syntactic structure of Javalette==
|
||||||
|
Non-terminals are enclosed between < and >.
|
||||||
|
The symbols -> (production), **|** (union)
|
||||||
|
and **eps** (empty rule) belong to the BNF notation.
|
||||||
|
All other symbols are terminals.
|
||||||
|
|
||||||
|
| //Program// | -> | //[TopDef]//
|
||||||
|
| //TopDef// | -> | //Type// //Ident// ``(`` //[Arg]// ``)`` //Block//
|
||||||
|
| //[TopDef]// | -> | //TopDef//
|
||||||
|
| | **|** | //TopDef// //[TopDef]//
|
||||||
|
| //Arg// | -> | //Type// //Ident//
|
||||||
|
| //[Arg]// | -> | **eps**
|
||||||
|
| | **|** | //Arg//
|
||||||
|
| | **|** | //Arg// ``,`` //[Arg]//
|
||||||
|
| //Block// | -> | ``{`` //[Stmt]// ``}``
|
||||||
|
| //[Stmt]// | -> | **eps**
|
||||||
|
| | **|** | //Stmt// //[Stmt]//
|
||||||
|
| //Stmt// | -> | ``;``
|
||||||
|
| | **|** | //Block//
|
||||||
|
| | **|** | //Type// //[Item]// ``;``
|
||||||
|
| | **|** | //Ident// ``=`` //Expr// ``;``
|
||||||
|
| | **|** | //Ident// ``++`` ``;``
|
||||||
|
| | **|** | //Ident// ``--`` ``;``
|
||||||
|
| | **|** | ``return`` //Expr// ``;``
|
||||||
|
| | **|** | ``return`` ``;``
|
||||||
|
| | **|** | ``if`` ``(`` //Expr// ``)`` //Stmt//
|
||||||
|
| | **|** | ``if`` ``(`` //Expr// ``)`` //Stmt// ``else`` //Stmt//
|
||||||
|
| | **|** | ``while`` ``(`` //Expr// ``)`` //Stmt//
|
||||||
|
| | **|** | //Expr// ``;``
|
||||||
|
| //Item// | -> | //Ident//
|
||||||
|
| | **|** | //Ident// ``=`` //Expr//
|
||||||
|
| //[Item]// | -> | //Item//
|
||||||
|
| | **|** | //Item// ``,`` //[Item]//
|
||||||
|
| //Type// | -> | ``int``
|
||||||
|
| | **|** | ``double``
|
||||||
|
| | **|** | ``boolean``
|
||||||
|
| | **|** | ``void``
|
||||||
|
| //[Type]// | -> | **eps**
|
||||||
|
| | **|** | //Type//
|
||||||
|
| | **|** | //Type// ``,`` //[Type]//
|
||||||
|
| //Expr6// | -> | //Ident//
|
||||||
|
| | **|** | //Integer//
|
||||||
|
| | **|** | //Double//
|
||||||
|
| | **|** | ``true``
|
||||||
|
| | **|** | ``false``
|
||||||
|
| | **|** | //Ident// ``(`` //[Expr]// ``)``
|
||||||
|
| | **|** | //String//
|
||||||
|
| | **|** | ``(`` //Expr// ``)``
|
||||||
|
| //Expr5// | -> | ``-`` //Expr6//
|
||||||
|
| | **|** | ``!`` //Expr6//
|
||||||
|
| | **|** | //Expr6//
|
||||||
|
| //Expr4// | -> | //Expr4// //MulOp// //Expr5//
|
||||||
|
| | **|** | //Expr5//
|
||||||
|
| //Expr3// | -> | //Expr3// //AddOp// //Expr4//
|
||||||
|
| | **|** | //Expr4//
|
||||||
|
| //Expr2// | -> | //Expr2// //RelOp// //Expr3//
|
||||||
|
| | **|** | //Expr3//
|
||||||
|
| //Expr1// | -> | //Expr2// ``&&`` //Expr1//
|
||||||
|
| | **|** | //Expr2//
|
||||||
|
| //Expr// | -> | //Expr1// ``||`` //Expr//
|
||||||
|
| | **|** | //Expr1//
|
||||||
|
| //[Expr]// | -> | **eps**
|
||||||
|
| | **|** | //Expr//
|
||||||
|
| | **|** | //Expr// ``,`` //[Expr]//
|
||||||
|
| //AddOp// | -> | ``+``
|
||||||
|
| | **|** | ``-``
|
||||||
|
| //MulOp// | -> | ``*``
|
||||||
|
| | **|** | ``/``
|
||||||
|
| | **|** | ``%``
|
||||||
|
| //RelOp// | -> | ``<``
|
||||||
|
| | **|** | ``<=``
|
||||||
|
| | **|** | ``>``
|
||||||
|
| | **|** | ``>=``
|
||||||
|
| | **|** | ``==``
|
||||||
|
| | **|** | ``!=``
|
||||||
|
|
||||||
|
|
131
DocJavalette.txt.bak
Normal file
131
DocJavalette.txt.bak
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
The Language Javalette
|
||||||
|
BNF Converter
|
||||||
|
|
||||||
|
|
||||||
|
%This txt2tags file is machine-generated by the BNF-converter
|
||||||
|
%Process by txt2tags to generate html or latex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This document was automatically generated by the //BNF-Converter//. It was generated together with the lexer, the parser, and the abstract syntax module, which guarantees that the document matches with the implementation of the language (provided no hand-hacking has taken place).
|
||||||
|
|
||||||
|
==The lexical structure of Javalette==
|
||||||
|
===Identifiers===
|
||||||
|
Identifiers //Ident// are unquoted strings beginning with a letter,
|
||||||
|
followed by any combination of letters, digits, and the characters ``_ '``
|
||||||
|
reserved words excluded.
|
||||||
|
|
||||||
|
|
||||||
|
===Literals===
|
||||||
|
Integer literals //Integer// are nonempty sequences of digits.
|
||||||
|
|
||||||
|
|
||||||
|
Double-precision float literals //Double// have the structure
|
||||||
|
indicated by the regular expression ``digit+ '.' digit+ ('e' ('-')? digit+)?`` i.e.\
|
||||||
|
two sequences of digits separated by a decimal point, optionally
|
||||||
|
followed by an unsigned or negative exponent.
|
||||||
|
|
||||||
|
|
||||||
|
String literals //String// have the form
|
||||||
|
``"``//x//``"``}, where //x// is any sequence of any characters
|
||||||
|
except ``"`` unless preceded by ``\``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
===Reserved words and symbols===
|
||||||
|
The set of reserved words is the set of terminals appearing in the grammar. Those reserved words that consist of non-letter characters are called symbols, and they are treated in a different way from those that are similar to identifiers. The lexer follows rules familiar from languages like Haskell, C, and Java, including longest match and spacing conventions.
|
||||||
|
|
||||||
|
The reserved words used in Javalette are the following:
|
||||||
|
| ``boolean`` | ``double`` | ``else`` | ``false``
|
||||||
|
| ``if`` | ``int`` | ``return`` | ``true``
|
||||||
|
| ``void`` | ``while`` | |
|
||||||
|
|
||||||
|
The symbols used in Javalette are the following:
|
||||||
|
| ( | ) | , | {
|
||||||
|
| } | ; | = | ++
|
||||||
|
| -- | - | ! | &&
|
||||||
|
| || | + | * | /
|
||||||
|
| % | < | <= | >
|
||||||
|
| >= | == | != |
|
||||||
|
|
||||||
|
===Comments===
|
||||||
|
Single-line comments begin with #, //.Multiple-line comments are enclosed with /* and */.
|
||||||
|
|
||||||
|
==The syntactic structure of Javalette==
|
||||||
|
Non-terminals are enclosed between < and >.
|
||||||
|
The symbols -> (production), **|** (union)
|
||||||
|
and **eps** (empty rule) belong to the BNF notation.
|
||||||
|
All other symbols are terminals.
|
||||||
|
|
||||||
|
| //Program// | -> | //[TopDef]//
|
||||||
|
| //TopDef// | -> | //Type// //Ident// ``(`` //[Arg]// ``)`` //Block//
|
||||||
|
| //[TopDef]// | -> | //TopDef//
|
||||||
|
| | **|** | //TopDef// //[TopDef]//
|
||||||
|
| //Arg// | -> | //Type// //Ident//
|
||||||
|
| //[Arg]// | -> | **eps**
|
||||||
|
| | **|** | //Arg//
|
||||||
|
| | **|** | //Arg// ``,`` //[Arg]//
|
||||||
|
| //Block// | -> | ``{`` //[Stmt]// ``}``
|
||||||
|
| //[Stmt]// | -> | **eps**
|
||||||
|
| | **|** | //Stmt// //[Stmt]//
|
||||||
|
| //Stmt// | -> | ``;``
|
||||||
|
| | **|** | //Block//
|
||||||
|
| | **|** | //Type// //[Item]// ``;``
|
||||||
|
| | **|** | //Ident// ``=`` //Expr// ``;``
|
||||||
|
| | **|** | //Ident// ``++`` ``;``
|
||||||
|
| | **|** | //Ident// ``--`` ``;``
|
||||||
|
| | **|** | ``return`` //Expr// ``;``
|
||||||
|
| | **|** | ``return`` ``;``
|
||||||
|
| | **|** | ``if`` ``(`` //Expr// ``)`` //Stmt//
|
||||||
|
| | **|** | ``if`` ``(`` //Expr// ``)`` //Stmt// ``else`` //Stmt//
|
||||||
|
| | **|** | ``while`` ``(`` //Expr// ``)`` //Stmt//
|
||||||
|
| | **|** | //Expr// ``;``
|
||||||
|
| //Item// | -> | //Ident//
|
||||||
|
| | **|** | //Ident// ``=`` //Expr//
|
||||||
|
| //[Item]// | -> | //Item//
|
||||||
|
| | **|** | //Item// ``,`` //[Item]//
|
||||||
|
| //Type// | -> | ``int``
|
||||||
|
| | **|** | ``double``
|
||||||
|
| | **|** | ``boolean``
|
||||||
|
| | **|** | ``void``
|
||||||
|
| //[Type]// | -> | **eps**
|
||||||
|
| | **|** | //Type//
|
||||||
|
| | **|** | //Type// ``,`` //[Type]//
|
||||||
|
| //Expr6// | -> | //Ident//
|
||||||
|
| | **|** | //Integer//
|
||||||
|
| | **|** | //Double//
|
||||||
|
| | **|** | ``true``
|
||||||
|
| | **|** | ``false``
|
||||||
|
| | **|** | //Ident// ``(`` //[Expr]// ``)``
|
||||||
|
| | **|** | //String//
|
||||||
|
| | **|** | ``(`` //Expr// ``)``
|
||||||
|
| //Expr5// | -> | ``-`` //Expr6//
|
||||||
|
| | **|** | ``!`` //Expr6//
|
||||||
|
| | **|** | //Expr6//
|
||||||
|
| //Expr4// | -> | //Expr4// //MulOp// //Expr5//
|
||||||
|
| | **|** | //Expr5//
|
||||||
|
| //Expr3// | -> | //Expr3// //AddOp// //Expr4//
|
||||||
|
| | **|** | //Expr4//
|
||||||
|
| //Expr2// | -> | //Expr2// //RelOp// //Expr3//
|
||||||
|
| | **|** | //Expr3//
|
||||||
|
| //Expr1// | -> | //Expr2// ``&&`` //Expr1//
|
||||||
|
| | **|** | //Expr2//
|
||||||
|
| //Expr// | -> | //Expr1// ``||`` //Expr//
|
||||||
|
| | **|** | //Expr1//
|
||||||
|
| //[Expr]// | -> | **eps**
|
||||||
|
| | **|** | //Expr//
|
||||||
|
| | **|** | //Expr// ``,`` //[Expr]//
|
||||||
|
| //AddOp// | -> | ``+``
|
||||||
|
| | **|** | ``-``
|
||||||
|
| //MulOp// | -> | ``*``
|
||||||
|
| | **|** | ``/``
|
||||||
|
| | **|** | ``%``
|
||||||
|
| //RelOp// | -> | ``<``
|
||||||
|
| | **|** | ``<=``
|
||||||
|
| | **|** | ``>``
|
||||||
|
| | **|** | ``>=``
|
||||||
|
| | **|** | ``==``
|
||||||
|
| | **|** | ``!=``
|
||||||
|
|
||||||
|
|
BIN
ErrM.hi
Normal file
BIN
ErrM.hi
Normal file
Binary file not shown.
26
ErrM.hs
Normal file
26
ErrM.hs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
-- BNF Converter: Error Monad
|
||||||
|
-- Copyright (C) 2004 Author: Aarne Ranta
|
||||||
|
|
||||||
|
-- This file comes with NO WARRANTY and may be used FOR ANY PURPOSE.
|
||||||
|
module ErrM where
|
||||||
|
|
||||||
|
-- the Error monad: like Maybe type with error msgs
|
||||||
|
|
||||||
|
import Control.Monad (MonadPlus(..), liftM)
|
||||||
|
|
||||||
|
data Err a = Ok a | Bad String
|
||||||
|
deriving (Read, Show, Eq, Ord)
|
||||||
|
|
||||||
|
instance Monad Err where
|
||||||
|
return = Ok
|
||||||
|
fail = Bad
|
||||||
|
Ok a >>= f = f a
|
||||||
|
Bad s >>= f = Bad s
|
||||||
|
|
||||||
|
instance Functor Err where
|
||||||
|
fmap = liftM
|
||||||
|
|
||||||
|
instance MonadPlus Err where
|
||||||
|
mzero = Bad "Err.mzero"
|
||||||
|
mplus (Bad _) y = y
|
||||||
|
mplus x _ = x
|
26
ErrM.hs.bak
Normal file
26
ErrM.hs.bak
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
-- BNF Converter: Error Monad
|
||||||
|
-- Copyright (C) 2004 Author: Aarne Ranta
|
||||||
|
|
||||||
|
-- This file comes with NO WARRANTY and may be used FOR ANY PURPOSE.
|
||||||
|
module ErrM where
|
||||||
|
|
||||||
|
-- the Error monad: like Maybe type with error msgs
|
||||||
|
|
||||||
|
import Control.Monad (MonadPlus(..), liftM)
|
||||||
|
|
||||||
|
data Err a = Ok a | Bad String
|
||||||
|
deriving (Read, Show, Eq, Ord)
|
||||||
|
|
||||||
|
instance Monad Err where
|
||||||
|
return = Ok
|
||||||
|
fail = Bad
|
||||||
|
Ok a >>= f = f a
|
||||||
|
Bad s >>= f = Bad s
|
||||||
|
|
||||||
|
instance Functor Err where
|
||||||
|
fmap = liftM
|
||||||
|
|
||||||
|
instance MonadPlus Err where
|
||||||
|
mzero = Bad "Err.mzero"
|
||||||
|
mplus (Bad _) y = y
|
||||||
|
mplus x _ = x
|
BIN
ErrM.o
Normal file
BIN
ErrM.o
Normal file
Binary file not shown.
132
Javalette.cf
Normal file
132
Javalette.cf
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
-- programs ------------------------------------------------
|
||||||
|
|
||||||
|
entrypoints Program ;
|
||||||
|
|
||||||
|
Program. Program ::= [TopDef] ;
|
||||||
|
|
||||||
|
FnDef. TopDef ::= Type Ident "(" [Arg] ")" Block ;
|
||||||
|
|
||||||
|
separator nonempty TopDef "" ;
|
||||||
|
|
||||||
|
Arg. Arg ::= Type Ident;
|
||||||
|
|
||||||
|
separator Arg "," ;
|
||||||
|
|
||||||
|
-- statements ----------------------------------------------
|
||||||
|
|
||||||
|
Block. Block ::= "{" [Stmt] "}" ;
|
||||||
|
|
||||||
|
separator Stmt "" ;
|
||||||
|
|
||||||
|
Empty. Stmt ::= ";" ;
|
||||||
|
|
||||||
|
BStmt. Stmt ::= Block ;
|
||||||
|
|
||||||
|
Decl. Stmt ::= Type [Item] ";" ;
|
||||||
|
|
||||||
|
NoInit. Item ::= Ident ;
|
||||||
|
|
||||||
|
Init. Item ::= Ident "=" Expr ;
|
||||||
|
|
||||||
|
separator nonempty Item "," ;
|
||||||
|
|
||||||
|
Ass. Stmt ::= Ident "=" Expr ";" ;
|
||||||
|
|
||||||
|
Incr. Stmt ::= Ident "++" ";" ;
|
||||||
|
|
||||||
|
Decr. Stmt ::= Ident "--" ";" ;
|
||||||
|
|
||||||
|
Ret. Stmt ::= "return" Expr ";" ;
|
||||||
|
|
||||||
|
VRet. Stmt ::= "return" ";" ;
|
||||||
|
|
||||||
|
Cond. Stmt ::= "if" "(" Expr ")" Stmt ;
|
||||||
|
|
||||||
|
CondElse. Stmt ::= "if" "(" Expr ")" Stmt "else" Stmt ;
|
||||||
|
|
||||||
|
While. Stmt ::= "while" "(" Expr ")" Stmt ;
|
||||||
|
|
||||||
|
SExp. Stmt ::= Expr ";" ;
|
||||||
|
|
||||||
|
-- Types ---------------------------------------------------
|
||||||
|
|
||||||
|
Int. Type ::= "int" ;
|
||||||
|
|
||||||
|
Doub. Type ::= "double" ;
|
||||||
|
|
||||||
|
Bool. Type ::= "boolean" ;
|
||||||
|
|
||||||
|
Void. Type ::= "void" ;
|
||||||
|
|
||||||
|
internal Fun. Type ::= Type "(" [Type] ")" ;
|
||||||
|
|
||||||
|
separator Type "," ;
|
||||||
|
|
||||||
|
-- Expressions ---------------------------------------------
|
||||||
|
|
||||||
|
EVar. Expr6 ::= Ident ;
|
||||||
|
|
||||||
|
ELitInt. Expr6 ::= Integer ;
|
||||||
|
|
||||||
|
ELitDoub. Expr6 ::= Double;
|
||||||
|
|
||||||
|
ELitTrue. Expr6 ::= "true" ;
|
||||||
|
|
||||||
|
ELitFalse. Expr6 ::= "false" ;
|
||||||
|
|
||||||
|
EApp. Expr6 ::= Ident "(" [Expr] ")" ;
|
||||||
|
|
||||||
|
EString. Expr6 ::= String ;
|
||||||
|
|
||||||
|
Neg. Expr5 ::= "-" Expr6 ;
|
||||||
|
|
||||||
|
Not. Expr5 ::= "!" Expr6 ;
|
||||||
|
|
||||||
|
EMul. Expr4 ::= Expr4 MulOp Expr5 ;
|
||||||
|
|
||||||
|
EAdd. Expr3 ::= Expr3 AddOp Expr4 ;
|
||||||
|
|
||||||
|
ERel. Expr2 ::= Expr2 RelOp Expr3 ;
|
||||||
|
|
||||||
|
EAnd. Expr1 ::= Expr2 "&&" Expr1 ;
|
||||||
|
|
||||||
|
EOr. Expr ::= Expr1 "||" Expr ;
|
||||||
|
|
||||||
|
internal TAnot. Expr ::= "<" Type ">" "(" Expr ")" ;
|
||||||
|
|
||||||
|
coercions Expr 6 ;
|
||||||
|
|
||||||
|
separator Expr "," ;
|
||||||
|
|
||||||
|
-- operators -----------------------------------------------
|
||||||
|
|
||||||
|
Plus. AddOp ::= "+" ;
|
||||||
|
|
||||||
|
Minus. AddOp ::= "-" ;
|
||||||
|
|
||||||
|
Times. MulOp ::= "*" ;
|
||||||
|
|
||||||
|
Div. MulOp ::= "/" ;
|
||||||
|
|
||||||
|
Mod. MulOp ::= "%" ;
|
||||||
|
|
||||||
|
LTH. RelOp ::= "<" ;
|
||||||
|
|
||||||
|
LE. RelOp ::= "<=" ;
|
||||||
|
|
||||||
|
GTH. RelOp ::= ">" ;
|
||||||
|
|
||||||
|
GE. RelOp ::= ">=" ;
|
||||||
|
|
||||||
|
EQU. RelOp ::= "==" ;
|
||||||
|
|
||||||
|
NE. RelOp ::= "!=" ;
|
||||||
|
|
||||||
|
-- comments ------------------------------------------------
|
||||||
|
|
||||||
|
comment "#" ;
|
||||||
|
|
||||||
|
comment "//" ;
|
||||||
|
|
||||||
|
comment "/*" "*/" ;
|
||||||
|
|
BIN
Javalette.hi
Normal file
BIN
Javalette.hi
Normal file
Binary file not shown.
36
Javalette.hs
Normal file
36
Javalette.hs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import System.Environment (getArgs)
|
||||||
|
import System.Exit (exitFailure)
|
||||||
|
import System.FilePath.Posix
|
||||||
|
|
||||||
|
import AbsJavalette
|
||||||
|
import LexJavalette
|
||||||
|
import ParJavalette
|
||||||
|
import ErrM
|
||||||
|
import PrintJavalette
|
||||||
|
|
||||||
|
import TypeChecker
|
||||||
|
import Compiler
|
||||||
|
|
||||||
|
|
||||||
|
check :: String -> IO ()
|
||||||
|
check s = case pProgram (myLexer s) of
|
||||||
|
Bad err -> do putStrLn "SYNTAX ERROR"
|
||||||
|
putStrLn err
|
||||||
|
exitFailure
|
||||||
|
Ok tree -> case typecheck tree of
|
||||||
|
Bad err -> do putStrLn "TYPE ERROR"
|
||||||
|
putStrLn err
|
||||||
|
exitFailure
|
||||||
|
Ok at -> do --putStrLn $ printTree at ++ "OK\n"
|
||||||
|
comp at
|
||||||
|
|
||||||
|
comp :: Program -> IO ()
|
||||||
|
comp p = do a <- getArgs
|
||||||
|
putStrLn $ compile p $ takeBaseName $ head a
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do args <- getArgs
|
||||||
|
case args of
|
||||||
|
[file] -> readFile file >>= check
|
||||||
|
_ -> do putStrLn "Usage: lab2 <SourceFile>"
|
||||||
|
exitFailure
|
30
Javalette.hs~
Normal file
30
Javalette.hs~
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import System.Environment (getArgs)
|
||||||
|
import System.Exit (exitFailure)
|
||||||
|
|
||||||
|
import AbsJavalette
|
||||||
|
import LexJavalette
|
||||||
|
import ParJavalette
|
||||||
|
import ErrM
|
||||||
|
|
||||||
|
import TypeChecker
|
||||||
|
|
||||||
|
|
||||||
|
-- driver
|
||||||
|
|
||||||
|
check :: String -> IO ()
|
||||||
|
check s = case pProgram (myLexer s) of
|
||||||
|
Bad err -> do putStrLn "SYNTAX ERROR"
|
||||||
|
putStrLn err
|
||||||
|
exitFailure
|
||||||
|
Ok tree -> case typecheck tree of
|
||||||
|
Bad err -> do putStrLn "TYPE ERROR"
|
||||||
|
putStrLn err
|
||||||
|
exitFailure
|
||||||
|
Ok _ -> putStrLn "OK\n" ++ printTree tree
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do args <- getArgs
|
||||||
|
case args of
|
||||||
|
[file] -> readFile file >>= check
|
||||||
|
_ -> do putStrLn "Usage: lab2 <SourceFile>"
|
||||||
|
exitFailure
|
BIN
Javalette.o
Normal file
BIN
Javalette.o
Normal file
Binary file not shown.
BIN
LexJavalette.hi
Normal file
BIN
LexJavalette.hi
Normal file
Binary file not shown.
340
LexJavalette.hs
Normal file
340
LexJavalette.hs
Normal file
File diff suppressed because one or more lines are too long
BIN
LexJavalette.o
Normal file
BIN
LexJavalette.o
Normal file
Binary file not shown.
135
LexJavalette.x
Normal file
135
LexJavalette.x
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
-- -*- haskell -*-
|
||||||
|
-- This Alex file was machine-generated by the BNF converter
|
||||||
|
{
|
||||||
|
{-# OPTIONS -fno-warn-incomplete-patterns #-}
|
||||||
|
module LexJavalette where
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$l = [a-zA-Z\192 - \255] # [\215 \247] -- isolatin1 letter FIXME
|
||||||
|
$c = [A-Z\192-\221] # [\215] -- capital isolatin1 letter FIXME
|
||||||
|
$s = [a-z\222-\255] # [\247] -- small isolatin1 letter FIXME
|
||||||
|
$d = [0-9] -- digit
|
||||||
|
$i = [$l $d _ '] -- identifier character
|
||||||
|
$u = [\0-\255] -- universal: any character
|
||||||
|
|
||||||
|
@rsyms = -- symbols and non-identifier-like reserved words
|
||||||
|
\( | \) | \, | \{ | \} | \; | \= | \+ \+ | \- \- | \- | \! | \& \& | \| \| | \< | \> | \+ | \* | \/ | \% | \< \= | \> \= | \= \= | \! \=
|
||||||
|
|
||||||
|
:-
|
||||||
|
"#" [.]* ; -- Toss single line comments
|
||||||
|
"//" [.]* ; -- Toss single line comments
|
||||||
|
"/*" ([$u # \*] | \* [$u # \/])* ("*")+ "/" ;
|
||||||
|
|
||||||
|
$white+ ;
|
||||||
|
@rsyms { tok (\p s -> PT p (TS $ share s)) }
|
||||||
|
|
||||||
|
$l $i* { tok (\p s -> PT p (eitherResIdent (TV . share) s)) }
|
||||||
|
\" ([$u # [\" \\ \n]] | (\\ (\" | \\ | \' | n | t)))* \"{ tok (\p s -> PT p (TL $ share $ unescapeInitTail s)) }
|
||||||
|
|
||||||
|
$d+ { tok (\p s -> PT p (TI $ share s)) }
|
||||||
|
$d+ \. $d+ (e (\-)? $d+)? { tok (\p s -> PT p (TD $ share s)) }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
tok f p s = f p s
|
||||||
|
|
||||||
|
share :: String -> String
|
||||||
|
share = id
|
||||||
|
|
||||||
|
data Tok =
|
||||||
|
TS !String -- reserved words and symbols
|
||||||
|
| TL !String -- string literals
|
||||||
|
| TI !String -- integer literals
|
||||||
|
| TV !String -- identifiers
|
||||||
|
| TD !String -- double precision float literals
|
||||||
|
| TC !String -- character literals
|
||||||
|
|
||||||
|
deriving (Eq,Show,Ord)
|
||||||
|
|
||||||
|
data Token =
|
||||||
|
PT Posn Tok
|
||||||
|
| Err Posn
|
||||||
|
deriving (Eq,Show,Ord)
|
||||||
|
|
||||||
|
tokenPos (PT (Pn _ l _) _ :_) = "line " ++ show l
|
||||||
|
tokenPos (Err (Pn _ l _) :_) = "line " ++ show l
|
||||||
|
tokenPos _ = "end of file"
|
||||||
|
|
||||||
|
posLineCol (Pn _ l c) = (l,c)
|
||||||
|
mkPosToken t@(PT p _) = (posLineCol p, prToken t)
|
||||||
|
|
||||||
|
prToken t = case t of
|
||||||
|
PT _ (TS s) -> s
|
||||||
|
PT _ (TI s) -> s
|
||||||
|
PT _ (TV s) -> s
|
||||||
|
PT _ (TD s) -> s
|
||||||
|
PT _ (TC s) -> s
|
||||||
|
|
||||||
|
_ -> show t
|
||||||
|
|
||||||
|
data BTree = N | B String Tok BTree BTree deriving (Show)
|
||||||
|
|
||||||
|
eitherResIdent :: (String -> Tok) -> String -> Tok
|
||||||
|
eitherResIdent tv s = treeFind resWords
|
||||||
|
where
|
||||||
|
treeFind N = tv s
|
||||||
|
treeFind (B a t left right) | s < a = treeFind left
|
||||||
|
| s > a = treeFind right
|
||||||
|
| s == a = t
|
||||||
|
|
||||||
|
resWords = b "int" (b "else" (b "double" (b "boolean" N N) N) (b "if" (b "false" N N) N)) (b "void" (b "true" (b "return" N N) N) (b "while" N N))
|
||||||
|
where b s = B s (TS s)
|
||||||
|
|
||||||
|
unescapeInitTail :: String -> String
|
||||||
|
unescapeInitTail = unesc . tail where
|
||||||
|
unesc s = case s of
|
||||||
|
'\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs
|
||||||
|
'\\':'n':cs -> '\n' : unesc cs
|
||||||
|
'\\':'t':cs -> '\t' : unesc cs
|
||||||
|
'"':[] -> []
|
||||||
|
c:cs -> c : unesc cs
|
||||||
|
_ -> []
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
-- Alex wrapper code.
|
||||||
|
-- A modified "posn" wrapper.
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
data Posn = Pn !Int !Int !Int
|
||||||
|
deriving (Eq, Show,Ord)
|
||||||
|
|
||||||
|
alexStartPos :: Posn
|
||||||
|
alexStartPos = Pn 0 1 1
|
||||||
|
|
||||||
|
alexMove :: Posn -> Char -> Posn
|
||||||
|
alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1)
|
||||||
|
alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1
|
||||||
|
alexMove (Pn a l c) _ = Pn (a+1) l (c+1)
|
||||||
|
|
||||||
|
type AlexInput = (Posn, -- current position,
|
||||||
|
Char, -- previous char
|
||||||
|
String) -- current input string
|
||||||
|
|
||||||
|
tokens :: String -> [Token]
|
||||||
|
tokens str = go (alexStartPos, '\n', str)
|
||||||
|
where
|
||||||
|
go :: (Posn, Char, String) -> [Token]
|
||||||
|
go inp@(pos, _, str) =
|
||||||
|
case alexScan inp 0 of
|
||||||
|
AlexEOF -> []
|
||||||
|
AlexError (pos, _, _) -> [Err pos]
|
||||||
|
AlexSkip inp' len -> go inp'
|
||||||
|
AlexToken inp' len act -> act pos (take len str) : (go inp')
|
||||||
|
|
||||||
|
alexGetChar :: AlexInput -> Maybe (Char,AlexInput)
|
||||||
|
alexGetChar (p, c, []) = Nothing
|
||||||
|
alexGetChar (p, _, (c:s)) =
|
||||||
|
let p' = alexMove p c
|
||||||
|
in p' `seq` Just (c, (p', c, s))
|
||||||
|
|
||||||
|
alexInputPrevChar :: AlexInput -> Char
|
||||||
|
alexInputPrevChar (p, c, s) = c
|
||||||
|
}
|
135
LexJavalette.x.bak
Normal file
135
LexJavalette.x.bak
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
-- -*- haskell -*-
|
||||||
|
-- This Alex file was machine-generated by the BNF converter
|
||||||
|
{
|
||||||
|
{-# OPTIONS -fno-warn-incomplete-patterns #-}
|
||||||
|
module LexJavalette where
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$l = [a-zA-Z\192 - \255] # [\215 \247] -- isolatin1 letter FIXME
|
||||||
|
$c = [A-Z\192-\221] # [\215] -- capital isolatin1 letter FIXME
|
||||||
|
$s = [a-z\222-\255] # [\247] -- small isolatin1 letter FIXME
|
||||||
|
$d = [0-9] -- digit
|
||||||
|
$i = [$l $d _ '] -- identifier character
|
||||||
|
$u = [\0-\255] -- universal: any character
|
||||||
|
|
||||||
|
@rsyms = -- symbols and non-identifier-like reserved words
|
||||||
|
\( | \) | \, | \{ | \} | \; | \= | \+ \+ | \- \- | \- | \! | \& \& | \| \| | \+ | \* | \/ | \% | \< | \< \= | \> | \> \= | \= \= | \! \=
|
||||||
|
|
||||||
|
:-
|
||||||
|
"#" [.]* ; -- Toss single line comments
|
||||||
|
"//" [.]* ; -- Toss single line comments
|
||||||
|
"/*" ([$u # \*] | \* [$u # \/])* ("*")+ "/" ;
|
||||||
|
|
||||||
|
$white+ ;
|
||||||
|
@rsyms { tok (\p s -> PT p (TS $ share s)) }
|
||||||
|
|
||||||
|
$l $i* { tok (\p s -> PT p (eitherResIdent (TV . share) s)) }
|
||||||
|
\" ([$u # [\" \\ \n]] | (\\ (\" | \\ | \' | n | t)))* \"{ tok (\p s -> PT p (TL $ share $ unescapeInitTail s)) }
|
||||||
|
|
||||||
|
$d+ { tok (\p s -> PT p (TI $ share s)) }
|
||||||
|
$d+ \. $d+ (e (\-)? $d+)? { tok (\p s -> PT p (TD $ share s)) }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
tok f p s = f p s
|
||||||
|
|
||||||
|
share :: String -> String
|
||||||
|
share = id
|
||||||
|
|
||||||
|
data Tok =
|
||||||
|
TS !String -- reserved words and symbols
|
||||||
|
| TL !String -- string literals
|
||||||
|
| TI !String -- integer literals
|
||||||
|
| TV !String -- identifiers
|
||||||
|
| TD !String -- double precision float literals
|
||||||
|
| TC !String -- character literals
|
||||||
|
|
||||||
|
deriving (Eq,Show,Ord)
|
||||||
|
|
||||||
|
data Token =
|
||||||
|
PT Posn Tok
|
||||||
|
| Err Posn
|
||||||
|
deriving (Eq,Show,Ord)
|
||||||
|
|
||||||
|
tokenPos (PT (Pn _ l _) _ :_) = "line " ++ show l
|
||||||
|
tokenPos (Err (Pn _ l _) :_) = "line " ++ show l
|
||||||
|
tokenPos _ = "end of file"
|
||||||
|
|
||||||
|
posLineCol (Pn _ l c) = (l,c)
|
||||||
|
mkPosToken t@(PT p _) = (posLineCol p, prToken t)
|
||||||
|
|
||||||
|
prToken t = case t of
|
||||||
|
PT _ (TS s) -> s
|
||||||
|
PT _ (TI s) -> s
|
||||||
|
PT _ (TV s) -> s
|
||||||
|
PT _ (TD s) -> s
|
||||||
|
PT _ (TC s) -> s
|
||||||
|
|
||||||
|
_ -> show t
|
||||||
|
|
||||||
|
data BTree = N | B String Tok BTree BTree deriving (Show)
|
||||||
|
|
||||||
|
eitherResIdent :: (String -> Tok) -> String -> Tok
|
||||||
|
eitherResIdent tv s = treeFind resWords
|
||||||
|
where
|
||||||
|
treeFind N = tv s
|
||||||
|
treeFind (B a t left right) | s < a = treeFind left
|
||||||
|
| s > a = treeFind right
|
||||||
|
| s == a = t
|
||||||
|
|
||||||
|
resWords = b "int" (b "else" (b "double" (b "boolean" N N) N) (b "if" (b "false" N N) N)) (b "void" (b "true" (b "return" N N) N) (b "while" N N))
|
||||||
|
where b s = B s (TS s)
|
||||||
|
|
||||||
|
unescapeInitTail :: String -> String
|
||||||
|
unescapeInitTail = unesc . tail where
|
||||||
|
unesc s = case s of
|
||||||
|
'\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs
|
||||||
|
'\\':'n':cs -> '\n' : unesc cs
|
||||||
|
'\\':'t':cs -> '\t' : unesc cs
|
||||||
|
'"':[] -> []
|
||||||
|
c:cs -> c : unesc cs
|
||||||
|
_ -> []
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
-- Alex wrapper code.
|
||||||
|
-- A modified "posn" wrapper.
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
data Posn = Pn !Int !Int !Int
|
||||||
|
deriving (Eq, Show,Ord)
|
||||||
|
|
||||||
|
alexStartPos :: Posn
|
||||||
|
alexStartPos = Pn 0 1 1
|
||||||
|
|
||||||
|
alexMove :: Posn -> Char -> Posn
|
||||||
|
alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1)
|
||||||
|
alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1
|
||||||
|
alexMove (Pn a l c) _ = Pn (a+1) l (c+1)
|
||||||
|
|
||||||
|
type AlexInput = (Posn, -- current position,
|
||||||
|
Char, -- previous char
|
||||||
|
String) -- current input string
|
||||||
|
|
||||||
|
tokens :: String -> [Token]
|
||||||
|
tokens str = go (alexStartPos, '\n', str)
|
||||||
|
where
|
||||||
|
go :: (Posn, Char, String) -> [Token]
|
||||||
|
go inp@(pos, _, str) =
|
||||||
|
case alexScan inp 0 of
|
||||||
|
AlexEOF -> []
|
||||||
|
AlexError (pos, _, _) -> [Err pos]
|
||||||
|
AlexSkip inp' len -> go inp'
|
||||||
|
AlexToken inp' len act -> act pos (take len str) : (go inp')
|
||||||
|
|
||||||
|
alexGetChar :: AlexInput -> Maybe (Char,AlexInput)
|
||||||
|
alexGetChar (p, c, []) = Nothing
|
||||||
|
alexGetChar (p, _, (c:s)) =
|
||||||
|
let p' = alexMove p c
|
||||||
|
in p' `seq` Just (c, (p', c, s))
|
||||||
|
|
||||||
|
alexInputPrevChar :: AlexInput -> Char
|
||||||
|
alexInputPrevChar (p, c, s) = c
|
||||||
|
}
|
14
Makefile
Normal file
14
Makefile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
all:
|
||||||
|
happy -gca ParJavalette.y
|
||||||
|
alex -g LexJavalette.x
|
||||||
|
latex DocJavalette.tex; dvips DocJavalette.dvi -o DocJavalette.ps
|
||||||
|
ghc --make TestJavalette.hs -o TestJavalette
|
||||||
|
ghc --make Javalette.hs -o jlc
|
||||||
|
clean:
|
||||||
|
-rm -f *.log *.aux *.hi *.o *.dvi
|
||||||
|
-rm -f DocJavalette.ps
|
||||||
|
distclean: clean
|
||||||
|
-rm -f DocJavalette.* LexJavalette.* ParJavalette.* LayoutJavalette.* SkelJavalette.* PrintJavalette.* TestJavalette.* AbsJavalette.* TestJavalette ErrM.* SharedString.* Javalette.dtd XMLJavalette.* Makefile*
|
||||||
|
|
||||||
|
jlc:
|
||||||
|
ghc --make Javalette.hs -o jlc
|
BIN
ParJavalette.hi
Normal file
BIN
ParJavalette.hi
Normal file
Binary file not shown.
1214
ParJavalette.hs
Normal file
1214
ParJavalette.hs
Normal file
File diff suppressed because it is too large
Load diff
BIN
ParJavalette.o
Normal file
BIN
ParJavalette.o
Normal file
Binary file not shown.
222
ParJavalette.y
Normal file
222
ParJavalette.y
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
-- This Happy file was machine-generated by the BNF converter
|
||||||
|
{
|
||||||
|
{-# OPTIONS -fno-warn-incomplete-patterns -fno-warn-overlapping-patterns #-}
|
||||||
|
module ParJavalette where
|
||||||
|
import AbsJavalette
|
||||||
|
import LexJavalette
|
||||||
|
import ErrM
|
||||||
|
}
|
||||||
|
|
||||||
|
%name pProgram Program
|
||||||
|
|
||||||
|
-- no lexer declaration
|
||||||
|
%monad { Err } { thenM } { returnM }
|
||||||
|
%tokentype { Token }
|
||||||
|
|
||||||
|
%token
|
||||||
|
'(' { PT _ (TS "(") }
|
||||||
|
')' { PT _ (TS ")") }
|
||||||
|
',' { PT _ (TS ",") }
|
||||||
|
'{' { PT _ (TS "{") }
|
||||||
|
'}' { PT _ (TS "}") }
|
||||||
|
';' { PT _ (TS ";") }
|
||||||
|
'=' { PT _ (TS "=") }
|
||||||
|
'++' { PT _ (TS "++") }
|
||||||
|
'--' { PT _ (TS "--") }
|
||||||
|
'-' { PT _ (TS "-") }
|
||||||
|
'!' { PT _ (TS "!") }
|
||||||
|
'&&' { PT _ (TS "&&") }
|
||||||
|
'||' { PT _ (TS "||") }
|
||||||
|
'<' { PT _ (TS "<") }
|
||||||
|
'>' { PT _ (TS ">") }
|
||||||
|
'+' { PT _ (TS "+") }
|
||||||
|
'*' { PT _ (TS "*") }
|
||||||
|
'/' { PT _ (TS "/") }
|
||||||
|
'%' { PT _ (TS "%") }
|
||||||
|
'<=' { PT _ (TS "<=") }
|
||||||
|
'>=' { PT _ (TS ">=") }
|
||||||
|
'==' { PT _ (TS "==") }
|
||||||
|
'!=' { PT _ (TS "!=") }
|
||||||
|
'boolean' { PT _ (TS "boolean") }
|
||||||
|
'double' { PT _ (TS "double") }
|
||||||
|
'else' { PT _ (TS "else") }
|
||||||
|
'false' { PT _ (TS "false") }
|
||||||
|
'if' { PT _ (TS "if") }
|
||||||
|
'int' { PT _ (TS "int") }
|
||||||
|
'return' { PT _ (TS "return") }
|
||||||
|
'true' { PT _ (TS "true") }
|
||||||
|
'void' { PT _ (TS "void") }
|
||||||
|
'while' { PT _ (TS "while") }
|
||||||
|
|
||||||
|
L_ident { PT _ (TV $$) }
|
||||||
|
L_integ { PT _ (TI $$) }
|
||||||
|
L_doubl { PT _ (TD $$) }
|
||||||
|
L_quoted { PT _ (TL $$) }
|
||||||
|
L_err { _ }
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
Ident :: { Ident } : L_ident { Ident $1 }
|
||||||
|
Integer :: { Integer } : L_integ { (read $1) :: Integer }
|
||||||
|
Double :: { Double } : L_doubl { (read $1) :: Double }
|
||||||
|
String :: { String } : L_quoted { $1 }
|
||||||
|
|
||||||
|
Program :: { Program }
|
||||||
|
Program : ListTopDef { Program $1 }
|
||||||
|
|
||||||
|
|
||||||
|
TopDef :: { TopDef }
|
||||||
|
TopDef : Type Ident '(' ListArg ')' Block { FnDef $1 $2 $4 $6 }
|
||||||
|
|
||||||
|
|
||||||
|
ListTopDef :: { [TopDef] }
|
||||||
|
ListTopDef : TopDef { (:[]) $1 }
|
||||||
|
| TopDef ListTopDef { (:) $1 $2 }
|
||||||
|
|
||||||
|
|
||||||
|
Arg :: { Arg }
|
||||||
|
Arg : Type Ident { Arg $1 $2 }
|
||||||
|
|
||||||
|
|
||||||
|
ListArg :: { [Arg] }
|
||||||
|
ListArg : {- empty -} { [] }
|
||||||
|
| Arg { (:[]) $1 }
|
||||||
|
| Arg ',' ListArg { (:) $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
Block :: { Block }
|
||||||
|
Block : '{' ListStmt '}' { Block (reverse $2) }
|
||||||
|
|
||||||
|
|
||||||
|
ListStmt :: { [Stmt] }
|
||||||
|
ListStmt : {- empty -} { [] }
|
||||||
|
| ListStmt Stmt { flip (:) $1 $2 }
|
||||||
|
|
||||||
|
|
||||||
|
Stmt :: { Stmt }
|
||||||
|
Stmt : ';' { Empty }
|
||||||
|
| Block { BStmt $1 }
|
||||||
|
| Type ListItem ';' { Decl $1 $2 }
|
||||||
|
| Ident '=' Expr ';' { Ass $1 $3 }
|
||||||
|
| Ident '++' ';' { Incr $1 }
|
||||||
|
| Ident '--' ';' { Decr $1 }
|
||||||
|
| 'return' Expr ';' { Ret $2 }
|
||||||
|
| 'return' ';' { VRet }
|
||||||
|
| 'if' '(' Expr ')' Stmt { Cond $3 $5 }
|
||||||
|
| 'if' '(' Expr ')' Stmt 'else' Stmt { CondElse $3 $5 $7 }
|
||||||
|
| 'while' '(' Expr ')' Stmt { While $3 $5 }
|
||||||
|
| Expr ';' { SExp $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Item :: { Item }
|
||||||
|
Item : Ident { NoInit $1 }
|
||||||
|
| Ident '=' Expr { Init $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
ListItem :: { [Item] }
|
||||||
|
ListItem : Item { (:[]) $1 }
|
||||||
|
| Item ',' ListItem { (:) $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
Type :: { Type }
|
||||||
|
Type : 'int' { Int }
|
||||||
|
| 'double' { Doub }
|
||||||
|
| 'boolean' { Bool }
|
||||||
|
| 'void' { Void }
|
||||||
|
|
||||||
|
|
||||||
|
ListType :: { [Type] }
|
||||||
|
ListType : {- empty -} { [] }
|
||||||
|
| Type { (:[]) $1 }
|
||||||
|
| Type ',' ListType { (:) $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr6 :: { Expr }
|
||||||
|
Expr6 : Ident { EVar $1 }
|
||||||
|
| Integer { ELitInt $1 }
|
||||||
|
| Double { ELitDoub $1 }
|
||||||
|
| 'true' { ELitTrue }
|
||||||
|
| 'false' { ELitFalse }
|
||||||
|
| Ident '(' ListExpr ')' { EApp $1 $3 }
|
||||||
|
| String { EString $1 }
|
||||||
|
| '(' Expr ')' { $2 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr5 :: { Expr }
|
||||||
|
Expr5 : '-' Expr6 { Neg $2 }
|
||||||
|
| '!' Expr6 { Not $2 }
|
||||||
|
| Expr6 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr4 :: { Expr }
|
||||||
|
Expr4 : Expr4 MulOp Expr5 { EMul $1 $2 $3 }
|
||||||
|
| Expr5 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr3 :: { Expr }
|
||||||
|
Expr3 : Expr3 AddOp Expr4 { EAdd $1 $2 $3 }
|
||||||
|
| Expr4 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr2 :: { Expr }
|
||||||
|
Expr2 : Expr2 RelOp Expr3 { ERel $1 $2 $3 }
|
||||||
|
| Expr3 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr1 :: { Expr }
|
||||||
|
Expr1 : Expr2 '&&' Expr1 { EAnd $1 $3 }
|
||||||
|
| Expr2 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr :: { Expr }
|
||||||
|
Expr : Expr1 '||' Expr { EOr $1 $3 }
|
||||||
|
| Expr1 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
ListExpr :: { [Expr] }
|
||||||
|
ListExpr : {- empty -} { [] }
|
||||||
|
| Expr { (:[]) $1 }
|
||||||
|
| Expr ',' ListExpr { (:) $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
AddOp :: { AddOp }
|
||||||
|
AddOp : '+' { Plus }
|
||||||
|
| '-' { Minus }
|
||||||
|
|
||||||
|
|
||||||
|
MulOp :: { MulOp }
|
||||||
|
MulOp : '*' { Times }
|
||||||
|
| '/' { Div }
|
||||||
|
| '%' { Mod }
|
||||||
|
|
||||||
|
|
||||||
|
RelOp :: { RelOp }
|
||||||
|
RelOp : '<' { LTH }
|
||||||
|
| '<=' { LE }
|
||||||
|
| '>' { GTH }
|
||||||
|
| '>=' { GE }
|
||||||
|
| '==' { EQU }
|
||||||
|
| '!=' { NE }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
returnM :: a -> Err a
|
||||||
|
returnM = return
|
||||||
|
|
||||||
|
thenM :: Err a -> (a -> Err b) -> Err b
|
||||||
|
thenM = (>>=)
|
||||||
|
|
||||||
|
happyError :: [Token] -> Err a
|
||||||
|
happyError ts =
|
||||||
|
Bad $ "syntax error at " ++ tokenPos ts ++
|
||||||
|
case ts of
|
||||||
|
[] -> []
|
||||||
|
[Err _] -> " due to lexer error"
|
||||||
|
_ -> " before " ++ unwords (map prToken (take 4 ts))
|
||||||
|
|
||||||
|
myLexer = tokens
|
||||||
|
}
|
||||||
|
|
222
ParJavalette.y.bak
Normal file
222
ParJavalette.y.bak
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
-- This Happy file was machine-generated by the BNF converter
|
||||||
|
{
|
||||||
|
{-# OPTIONS -fno-warn-incomplete-patterns -fno-warn-overlapping-patterns #-}
|
||||||
|
module ParJavalette where
|
||||||
|
import AbsJavalette
|
||||||
|
import LexJavalette
|
||||||
|
import ErrM
|
||||||
|
}
|
||||||
|
|
||||||
|
%name pProgram Program
|
||||||
|
|
||||||
|
-- no lexer declaration
|
||||||
|
%monad { Err } { thenM } { returnM }
|
||||||
|
%tokentype { Token }
|
||||||
|
|
||||||
|
%token
|
||||||
|
'(' { PT _ (TS "(") }
|
||||||
|
')' { PT _ (TS ")") }
|
||||||
|
',' { PT _ (TS ",") }
|
||||||
|
'{' { PT _ (TS "{") }
|
||||||
|
'}' { PT _ (TS "}") }
|
||||||
|
';' { PT _ (TS ";") }
|
||||||
|
'=' { PT _ (TS "=") }
|
||||||
|
'++' { PT _ (TS "++") }
|
||||||
|
'--' { PT _ (TS "--") }
|
||||||
|
'-' { PT _ (TS "-") }
|
||||||
|
'!' { PT _ (TS "!") }
|
||||||
|
'&&' { PT _ (TS "&&") }
|
||||||
|
'||' { PT _ (TS "||") }
|
||||||
|
'+' { PT _ (TS "+") }
|
||||||
|
'*' { PT _ (TS "*") }
|
||||||
|
'/' { PT _ (TS "/") }
|
||||||
|
'%' { PT _ (TS "%") }
|
||||||
|
'<' { PT _ (TS "<") }
|
||||||
|
'<=' { PT _ (TS "<=") }
|
||||||
|
'>' { PT _ (TS ">") }
|
||||||
|
'>=' { PT _ (TS ">=") }
|
||||||
|
'==' { PT _ (TS "==") }
|
||||||
|
'!=' { PT _ (TS "!=") }
|
||||||
|
'boolean' { PT _ (TS "boolean") }
|
||||||
|
'double' { PT _ (TS "double") }
|
||||||
|
'else' { PT _ (TS "else") }
|
||||||
|
'false' { PT _ (TS "false") }
|
||||||
|
'if' { PT _ (TS "if") }
|
||||||
|
'int' { PT _ (TS "int") }
|
||||||
|
'return' { PT _ (TS "return") }
|
||||||
|
'true' { PT _ (TS "true") }
|
||||||
|
'void' { PT _ (TS "void") }
|
||||||
|
'while' { PT _ (TS "while") }
|
||||||
|
|
||||||
|
L_ident { PT _ (TV $$) }
|
||||||
|
L_integ { PT _ (TI $$) }
|
||||||
|
L_doubl { PT _ (TD $$) }
|
||||||
|
L_quoted { PT _ (TL $$) }
|
||||||
|
L_err { _ }
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
Ident :: { Ident } : L_ident { Ident $1 }
|
||||||
|
Integer :: { Integer } : L_integ { (read $1) :: Integer }
|
||||||
|
Double :: { Double } : L_doubl { (read $1) :: Double }
|
||||||
|
String :: { String } : L_quoted { $1 }
|
||||||
|
|
||||||
|
Program :: { Program }
|
||||||
|
Program : ListTopDef { Program $1 }
|
||||||
|
|
||||||
|
|
||||||
|
TopDef :: { TopDef }
|
||||||
|
TopDef : Type Ident '(' ListArg ')' Block { FnDef $1 $2 $4 $6 }
|
||||||
|
|
||||||
|
|
||||||
|
ListTopDef :: { [TopDef] }
|
||||||
|
ListTopDef : TopDef { (:[]) $1 }
|
||||||
|
| TopDef ListTopDef { (:) $1 $2 }
|
||||||
|
|
||||||
|
|
||||||
|
Arg :: { Arg }
|
||||||
|
Arg : Type Ident { Arg $1 $2 }
|
||||||
|
|
||||||
|
|
||||||
|
ListArg :: { [Arg] }
|
||||||
|
ListArg : {- empty -} { [] }
|
||||||
|
| Arg { (:[]) $1 }
|
||||||
|
| Arg ',' ListArg { (:) $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
Block :: { Block }
|
||||||
|
Block : '{' ListStmt '}' { Block (reverse $2) }
|
||||||
|
|
||||||
|
|
||||||
|
ListStmt :: { [Stmt] }
|
||||||
|
ListStmt : {- empty -} { [] }
|
||||||
|
| ListStmt Stmt { flip (:) $1 $2 }
|
||||||
|
|
||||||
|
|
||||||
|
Stmt :: { Stmt }
|
||||||
|
Stmt : ';' { Empty }
|
||||||
|
| Block { BStmt $1 }
|
||||||
|
| Type ListItem ';' { Decl $1 $2 }
|
||||||
|
| Ident '=' Expr ';' { Ass $1 $3 }
|
||||||
|
| Ident '++' ';' { Incr $1 }
|
||||||
|
| Ident '--' ';' { Decr $1 }
|
||||||
|
| 'return' Expr ';' { Ret $2 }
|
||||||
|
| 'return' ';' { VRet }
|
||||||
|
| 'if' '(' Expr ')' Stmt { Cond $3 $5 }
|
||||||
|
| 'if' '(' Expr ')' Stmt 'else' Stmt { CondElse $3 $5 $7 }
|
||||||
|
| 'while' '(' Expr ')' Stmt { While $3 $5 }
|
||||||
|
| Expr ';' { SExp $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Item :: { Item }
|
||||||
|
Item : Ident { NoInit $1 }
|
||||||
|
| Ident '=' Expr { Init $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
ListItem :: { [Item] }
|
||||||
|
ListItem : Item { (:[]) $1 }
|
||||||
|
| Item ',' ListItem { (:) $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
Type :: { Type }
|
||||||
|
Type : 'int' { Int }
|
||||||
|
| 'double' { Doub }
|
||||||
|
| 'boolean' { Bool }
|
||||||
|
| 'void' { Void }
|
||||||
|
|
||||||
|
|
||||||
|
ListType :: { [Type] }
|
||||||
|
ListType : {- empty -} { [] }
|
||||||
|
| Type { (:[]) $1 }
|
||||||
|
| Type ',' ListType { (:) $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr6 :: { Expr }
|
||||||
|
Expr6 : Ident { EVar $1 }
|
||||||
|
| Integer { ELitInt $1 }
|
||||||
|
| Double { ELitDoub $1 }
|
||||||
|
| 'true' { ELitTrue }
|
||||||
|
| 'false' { ELitFalse }
|
||||||
|
| Ident '(' ListExpr ')' { EApp $1 $3 }
|
||||||
|
| String { EString $1 }
|
||||||
|
| '(' Expr ')' { $2 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr5 :: { Expr }
|
||||||
|
Expr5 : '-' Expr6 { Neg $2 }
|
||||||
|
| '!' Expr6 { Not $2 }
|
||||||
|
| Expr6 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr4 :: { Expr }
|
||||||
|
Expr4 : Expr4 MulOp Expr5 { EMul $1 $2 $3 }
|
||||||
|
| Expr5 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr3 :: { Expr }
|
||||||
|
Expr3 : Expr3 AddOp Expr4 { EAdd $1 $2 $3 }
|
||||||
|
| Expr4 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr2 :: { Expr }
|
||||||
|
Expr2 : Expr2 RelOp Expr3 { ERel $1 $2 $3 }
|
||||||
|
| Expr3 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr1 :: { Expr }
|
||||||
|
Expr1 : Expr2 '&&' Expr1 { EAnd $1 $3 }
|
||||||
|
| Expr2 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
Expr :: { Expr }
|
||||||
|
Expr : Expr1 '||' Expr { EOr $1 $3 }
|
||||||
|
| Expr1 { $1 }
|
||||||
|
|
||||||
|
|
||||||
|
ListExpr :: { [Expr] }
|
||||||
|
ListExpr : {- empty -} { [] }
|
||||||
|
| Expr { (:[]) $1 }
|
||||||
|
| Expr ',' ListExpr { (:) $1 $3 }
|
||||||
|
|
||||||
|
|
||||||
|
AddOp :: { AddOp }
|
||||||
|
AddOp : '+' { Plus }
|
||||||
|
| '-' { Minus }
|
||||||
|
|
||||||
|
|
||||||
|
MulOp :: { MulOp }
|
||||||
|
MulOp : '*' { Times }
|
||||||
|
| '/' { Div }
|
||||||
|
| '%' { Mod }
|
||||||
|
|
||||||
|
|
||||||
|
RelOp :: { RelOp }
|
||||||
|
RelOp : '<' { LTH }
|
||||||
|
| '<=' { LE }
|
||||||
|
| '>' { GTH }
|
||||||
|
| '>=' { GE }
|
||||||
|
| '==' { EQU }
|
||||||
|
| '!=' { NE }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
returnM :: a -> Err a
|
||||||
|
returnM = return
|
||||||
|
|
||||||
|
thenM :: Err a -> (a -> Err b) -> Err b
|
||||||
|
thenM = (>>=)
|
||||||
|
|
||||||
|
happyError :: [Token] -> Err a
|
||||||
|
happyError ts =
|
||||||
|
Bad $ "syntax error at " ++ tokenPos ts ++
|
||||||
|
case ts of
|
||||||
|
[] -> []
|
||||||
|
[Err _] -> " due to lexer error"
|
||||||
|
_ -> " before " ++ unwords (map prToken (take 4 ts))
|
||||||
|
|
||||||
|
myLexer = tokens
|
||||||
|
}
|
||||||
|
|
BIN
PrintJavalette.hi
Normal file
BIN
PrintJavalette.hi
Normal file
Binary file not shown.
199
PrintJavalette.hs
Normal file
199
PrintJavalette.hs
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
{-# OPTIONS -fno-warn-incomplete-patterns #-}
|
||||||
|
module PrintJavalette where
|
||||||
|
|
||||||
|
-- pretty-printer generated by the BNF converter
|
||||||
|
|
||||||
|
import AbsJavalette
|
||||||
|
import Char
|
||||||
|
|
||||||
|
-- the top-level printing method
|
||||||
|
printTree :: Print a => a -> String
|
||||||
|
printTree = render . prt 0
|
||||||
|
|
||||||
|
type Doc = [ShowS] -> [ShowS]
|
||||||
|
|
||||||
|
doc :: ShowS -> Doc
|
||||||
|
doc = (:)
|
||||||
|
|
||||||
|
render :: Doc -> String
|
||||||
|
render d = rend 0 (map ($ "") $ d []) "" where
|
||||||
|
rend i ss = case ss of
|
||||||
|
"[" :ts -> showChar '[' . rend i ts
|
||||||
|
"(" :ts -> showChar '(' . rend i ts
|
||||||
|
"{" :ts -> showChar '{' . new (i+1) . rend (i+1) ts
|
||||||
|
"}" : ";":ts -> new (i-1) . space "}" . showChar ';' . new (i-1) . rend (i-1) ts
|
||||||
|
"}" :ts -> new (i-1) . showChar '}' . new (i-1) . rend (i-1) ts
|
||||||
|
";" :ts -> showChar ';' . new i . rend i ts
|
||||||
|
t : "," :ts -> showString t . space "," . rend i ts
|
||||||
|
t : ")" :ts -> showString t . showChar ')' . rend i ts
|
||||||
|
t : "]" :ts -> showString t . showChar ']' . rend i ts
|
||||||
|
t :ts -> space t . rend i ts
|
||||||
|
_ -> id
|
||||||
|
new i = showChar '\n' . replicateS (2*i) (showChar ' ') . dropWhile isSpace
|
||||||
|
space t = showString t . (\s -> if null s then "" else (' ':s))
|
||||||
|
|
||||||
|
parenth :: Doc -> Doc
|
||||||
|
parenth ss = doc (showChar '(') . ss . doc (showChar ')')
|
||||||
|
|
||||||
|
concatS :: [ShowS] -> ShowS
|
||||||
|
concatS = foldr (.) id
|
||||||
|
|
||||||
|
concatD :: [Doc] -> Doc
|
||||||
|
concatD = foldr (.) id
|
||||||
|
|
||||||
|
replicateS :: Int -> ShowS -> ShowS
|
||||||
|
replicateS n f = concatS (replicate n f)
|
||||||
|
|
||||||
|
-- the printer class does the job
|
||||||
|
class Print a where
|
||||||
|
prt :: Int -> a -> Doc
|
||||||
|
prtList :: [a] -> Doc
|
||||||
|
prtList = concatD . map (prt 0)
|
||||||
|
|
||||||
|
instance Print a => Print [a] where
|
||||||
|
prt _ = prtList
|
||||||
|
|
||||||
|
instance Print Char where
|
||||||
|
prt _ s = doc (showChar '\'' . mkEsc '\'' s . showChar '\'')
|
||||||
|
prtList s = doc (showChar '"' . concatS (map (mkEsc '"') s) . showChar '"')
|
||||||
|
|
||||||
|
mkEsc :: Char -> Char -> ShowS
|
||||||
|
mkEsc q s = case s of
|
||||||
|
_ | s == q -> showChar '\\' . showChar s
|
||||||
|
'\\'-> showString "\\\\"
|
||||||
|
'\n' -> showString "\\n"
|
||||||
|
'\t' -> showString "\\t"
|
||||||
|
_ -> showChar s
|
||||||
|
|
||||||
|
prPrec :: Int -> Int -> Doc -> Doc
|
||||||
|
prPrec i j = if j<i then parenth else id
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Integer where
|
||||||
|
prt _ x = doc (shows x)
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Double where
|
||||||
|
prt _ x = doc (shows x)
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Ident where
|
||||||
|
prt _ (Ident i) = doc (showString i)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Program where
|
||||||
|
prt i e = case e of
|
||||||
|
Program topdefs -> prPrec i 0 (concatD [prt 0 topdefs])
|
||||||
|
|
||||||
|
|
||||||
|
instance Print TopDef where
|
||||||
|
prt i e = case e of
|
||||||
|
FnDef type' id args block -> prPrec i 0 (concatD [prt 0 type' , prt 0 id , doc (showString "(") , prt 0 args , doc (showString ")") , prt 0 block])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Arg where
|
||||||
|
prt i e = case e of
|
||||||
|
Arg type' id -> prPrec i 0 (concatD [prt 0 type' , prt 0 id])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[] -> (concatD [])
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Block where
|
||||||
|
prt i e = case e of
|
||||||
|
Block stmts -> prPrec i 0 (concatD [doc (showString "{") , prt 0 stmts , doc (showString "}")])
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Stmt where
|
||||||
|
prt i e = case e of
|
||||||
|
Empty -> prPrec i 0 (concatD [doc (showString ";")])
|
||||||
|
BStmt block -> prPrec i 0 (concatD [prt 0 block])
|
||||||
|
Decl type' items -> prPrec i 0 (concatD [prt 0 type' , prt 0 items , doc (showString ";")])
|
||||||
|
Ass id expr -> prPrec i 0 (concatD [prt 0 id , doc (showString "=") , prt 0 expr , doc (showString ";")])
|
||||||
|
Incr id -> prPrec i 0 (concatD [prt 0 id , doc (showString "++") , doc (showString ";")])
|
||||||
|
Decr id -> prPrec i 0 (concatD [prt 0 id , doc (showString "--") , doc (showString ";")])
|
||||||
|
Ret expr -> prPrec i 0 (concatD [doc (showString "return") , prt 0 expr , doc (showString ";")])
|
||||||
|
VRet -> prPrec i 0 (concatD [doc (showString "return") , doc (showString ";")])
|
||||||
|
Cond expr stmt -> prPrec i 0 (concatD [doc (showString "if") , doc (showString "(") , prt 0 expr , doc (showString ")") , prt 0 stmt])
|
||||||
|
CondElse expr stmt0 stmt -> prPrec i 0 (concatD [doc (showString "if") , doc (showString "(") , prt 0 expr , doc (showString ")") , prt 0 stmt0 , doc (showString "else") , prt 0 stmt])
|
||||||
|
While expr stmt -> prPrec i 0 (concatD [doc (showString "while") , doc (showString "(") , prt 0 expr , doc (showString ")") , prt 0 stmt])
|
||||||
|
SExp expr -> prPrec i 0 (concatD [prt 0 expr , doc (showString ";")])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[] -> (concatD [])
|
||||||
|
x:xs -> (concatD [prt 0 x , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Item where
|
||||||
|
prt i e = case e of
|
||||||
|
NoInit id -> prPrec i 0 (concatD [prt 0 id])
|
||||||
|
Init id expr -> prPrec i 0 (concatD [prt 0 id , doc (showString "=") , prt 0 expr])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Type where
|
||||||
|
prt i e = case e of
|
||||||
|
Int -> prPrec i 0 (concatD [doc (showString "int")])
|
||||||
|
Doub -> prPrec i 0 (concatD [doc (showString "double")])
|
||||||
|
Bool -> prPrec i 0 (concatD [doc (showString "boolean")])
|
||||||
|
Void -> prPrec i 0 (concatD [doc (showString "void")])
|
||||||
|
Fun type' types -> prPrec i 0 (concatD [prt 0 type' , doc (showString "(") , prt 0 types , doc (showString ")")])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[] -> (concatD [])
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Expr where
|
||||||
|
prt i e = case e of
|
||||||
|
EVar id -> prPrec i 6 (concatD [prt 0 id])
|
||||||
|
ELitInt n -> prPrec i 6 (concatD [prt 0 n])
|
||||||
|
ELitDoub d -> prPrec i 6 (concatD [prt 0 d])
|
||||||
|
ELitTrue -> prPrec i 6 (concatD [doc (showString "true")])
|
||||||
|
ELitFalse -> prPrec i 6 (concatD [doc (showString "false")])
|
||||||
|
EApp id exprs -> prPrec i 6 (concatD [prt 0 id , doc (showString "(") , prt 0 exprs , doc (showString ")")])
|
||||||
|
EString str -> prPrec i 6 (concatD [prt 0 str])
|
||||||
|
Neg expr -> prPrec i 5 (concatD [doc (showString "-") , prt 6 expr])
|
||||||
|
Not expr -> prPrec i 5 (concatD [doc (showString "!") , prt 6 expr])
|
||||||
|
EMul expr0 mulop expr -> prPrec i 4 (concatD [prt 4 expr0 , prt 0 mulop , prt 5 expr])
|
||||||
|
EAdd expr0 addop expr -> prPrec i 3 (concatD [prt 3 expr0 , prt 0 addop , prt 4 expr])
|
||||||
|
ERel expr0 relop expr -> prPrec i 2 (concatD [prt 2 expr0 , prt 0 relop , prt 3 expr])
|
||||||
|
EAnd expr0 expr -> prPrec i 1 (concatD [prt 2 expr0 , doc (showString "&&") , prt 1 expr])
|
||||||
|
EOr expr0 expr -> prPrec i 0 (concatD [prt 1 expr0 , doc (showString "||") , prt 0 expr])
|
||||||
|
TAnot type' expr -> prPrec i 0 (concatD [doc (showString "<") , prt 0 type' , doc (showString ">") , doc (showString "(") , prt 0 expr , doc (showString ")")])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[] -> (concatD [])
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print AddOp where
|
||||||
|
prt i e = case e of
|
||||||
|
Plus -> prPrec i 0 (concatD [doc (showString "+")])
|
||||||
|
Minus -> prPrec i 0 (concatD [doc (showString "-")])
|
||||||
|
|
||||||
|
|
||||||
|
instance Print MulOp where
|
||||||
|
prt i e = case e of
|
||||||
|
Times -> prPrec i 0 (concatD [doc (showString "*")])
|
||||||
|
Div -> prPrec i 0 (concatD [doc (showString "/")])
|
||||||
|
Mod -> prPrec i 0 (concatD [doc (showString "%")])
|
||||||
|
|
||||||
|
|
||||||
|
instance Print RelOp where
|
||||||
|
prt i e = case e of
|
||||||
|
LTH -> prPrec i 0 (concatD [doc (showString "<")])
|
||||||
|
LE -> prPrec i 0 (concatD [doc (showString "<=")])
|
||||||
|
GTH -> prPrec i 0 (concatD [doc (showString ">")])
|
||||||
|
GE -> prPrec i 0 (concatD [doc (showString ">=")])
|
||||||
|
EQU -> prPrec i 0 (concatD [doc (showString "==")])
|
||||||
|
NE -> prPrec i 0 (concatD [doc (showString "!=")])
|
||||||
|
|
||||||
|
|
||||||
|
|
198
PrintJavalette.hs.bak
Normal file
198
PrintJavalette.hs.bak
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
{-# OPTIONS -fno-warn-incomplete-patterns #-}
|
||||||
|
module PrintJavalette where
|
||||||
|
|
||||||
|
-- pretty-printer generated by the BNF converter
|
||||||
|
|
||||||
|
import AbsJavalette
|
||||||
|
import Char
|
||||||
|
|
||||||
|
-- the top-level printing method
|
||||||
|
printTree :: Print a => a -> String
|
||||||
|
printTree = render . prt 0
|
||||||
|
|
||||||
|
type Doc = [ShowS] -> [ShowS]
|
||||||
|
|
||||||
|
doc :: ShowS -> Doc
|
||||||
|
doc = (:)
|
||||||
|
|
||||||
|
render :: Doc -> String
|
||||||
|
render d = rend 0 (map ($ "") $ d []) "" where
|
||||||
|
rend i ss = case ss of
|
||||||
|
"[" :ts -> showChar '[' . rend i ts
|
||||||
|
"(" :ts -> showChar '(' . rend i ts
|
||||||
|
"{" :ts -> showChar '{' . new (i+1) . rend (i+1) ts
|
||||||
|
"}" : ";":ts -> new (i-1) . space "}" . showChar ';' . new (i-1) . rend (i-1) ts
|
||||||
|
"}" :ts -> new (i-1) . showChar '}' . new (i-1) . rend (i-1) ts
|
||||||
|
";" :ts -> showChar ';' . new i . rend i ts
|
||||||
|
t : "," :ts -> showString t . space "," . rend i ts
|
||||||
|
t : ")" :ts -> showString t . showChar ')' . rend i ts
|
||||||
|
t : "]" :ts -> showString t . showChar ']' . rend i ts
|
||||||
|
t :ts -> space t . rend i ts
|
||||||
|
_ -> id
|
||||||
|
new i = showChar '\n' . replicateS (2*i) (showChar ' ') . dropWhile isSpace
|
||||||
|
space t = showString t . (\s -> if null s then "" else (' ':s))
|
||||||
|
|
||||||
|
parenth :: Doc -> Doc
|
||||||
|
parenth ss = doc (showChar '(') . ss . doc (showChar ')')
|
||||||
|
|
||||||
|
concatS :: [ShowS] -> ShowS
|
||||||
|
concatS = foldr (.) id
|
||||||
|
|
||||||
|
concatD :: [Doc] -> Doc
|
||||||
|
concatD = foldr (.) id
|
||||||
|
|
||||||
|
replicateS :: Int -> ShowS -> ShowS
|
||||||
|
replicateS n f = concatS (replicate n f)
|
||||||
|
|
||||||
|
-- the printer class does the job
|
||||||
|
class Print a where
|
||||||
|
prt :: Int -> a -> Doc
|
||||||
|
prtList :: [a] -> Doc
|
||||||
|
prtList = concatD . map (prt 0)
|
||||||
|
|
||||||
|
instance Print a => Print [a] where
|
||||||
|
prt _ = prtList
|
||||||
|
|
||||||
|
instance Print Char where
|
||||||
|
prt _ s = doc (showChar '\'' . mkEsc '\'' s . showChar '\'')
|
||||||
|
prtList s = doc (showChar '"' . concatS (map (mkEsc '"') s) . showChar '"')
|
||||||
|
|
||||||
|
mkEsc :: Char -> Char -> ShowS
|
||||||
|
mkEsc q s = case s of
|
||||||
|
_ | s == q -> showChar '\\' . showChar s
|
||||||
|
'\\'-> showString "\\\\"
|
||||||
|
'\n' -> showString "\\n"
|
||||||
|
'\t' -> showString "\\t"
|
||||||
|
_ -> showChar s
|
||||||
|
|
||||||
|
prPrec :: Int -> Int -> Doc -> Doc
|
||||||
|
prPrec i j = if j<i then parenth else id
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Integer where
|
||||||
|
prt _ x = doc (shows x)
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Double where
|
||||||
|
prt _ x = doc (shows x)
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Ident where
|
||||||
|
prt _ (Ident i) = doc (showString i)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Program where
|
||||||
|
prt i e = case e of
|
||||||
|
Program topdefs -> prPrec i 0 (concatD [prt 0 topdefs])
|
||||||
|
|
||||||
|
|
||||||
|
instance Print TopDef where
|
||||||
|
prt i e = case e of
|
||||||
|
FnDef type' id args block -> prPrec i 0 (concatD [prt 0 type' , prt 0 id , doc (showString "(") , prt 0 args , doc (showString ")") , prt 0 block])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Arg where
|
||||||
|
prt i e = case e of
|
||||||
|
Arg type' id -> prPrec i 0 (concatD [prt 0 type' , prt 0 id])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[] -> (concatD [])
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Block where
|
||||||
|
prt i e = case e of
|
||||||
|
Block stmts -> prPrec i 0 (concatD [doc (showString "{") , prt 0 stmts , doc (showString "}")])
|
||||||
|
|
||||||
|
|
||||||
|
instance Print Stmt where
|
||||||
|
prt i e = case e of
|
||||||
|
Empty -> prPrec i 0 (concatD [doc (showString ";")])
|
||||||
|
BStmt block -> prPrec i 0 (concatD [prt 0 block])
|
||||||
|
Decl type' items -> prPrec i 0 (concatD [prt 0 type' , prt 0 items , doc (showString ";")])
|
||||||
|
Ass id expr -> prPrec i 0 (concatD [prt 0 id , doc (showString "=") , prt 0 expr , doc (showString ";")])
|
||||||
|
Incr id -> prPrec i 0 (concatD [prt 0 id , doc (showString "++") , doc (showString ";")])
|
||||||
|
Decr id -> prPrec i 0 (concatD [prt 0 id , doc (showString "--") , doc (showString ";")])
|
||||||
|
Ret expr -> prPrec i 0 (concatD [doc (showString "return") , prt 0 expr , doc (showString ";")])
|
||||||
|
VRet -> prPrec i 0 (concatD [doc (showString "return") , doc (showString ";")])
|
||||||
|
Cond expr stmt -> prPrec i 0 (concatD [doc (showString "if") , doc (showString "(") , prt 0 expr , doc (showString ")") , prt 0 stmt])
|
||||||
|
CondElse expr stmt0 stmt -> prPrec i 0 (concatD [doc (showString "if") , doc (showString "(") , prt 0 expr , doc (showString ")") , prt 0 stmt0 , doc (showString "else") , prt 0 stmt])
|
||||||
|
While expr stmt -> prPrec i 0 (concatD [doc (showString "while") , doc (showString "(") , prt 0 expr , doc (showString ")") , prt 0 stmt])
|
||||||
|
SExp expr -> prPrec i 0 (concatD [prt 0 expr , doc (showString ";")])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[] -> (concatD [])
|
||||||
|
x:xs -> (concatD [prt 0 x , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Item where
|
||||||
|
prt i e = case e of
|
||||||
|
NoInit id -> prPrec i 0 (concatD [prt 0 id])
|
||||||
|
Init id expr -> prPrec i 0 (concatD [prt 0 id , doc (showString "=") , prt 0 expr])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Type where
|
||||||
|
prt i e = case e of
|
||||||
|
Int -> prPrec i 0 (concatD [doc (showString "int")])
|
||||||
|
Doub -> prPrec i 0 (concatD [doc (showString "double")])
|
||||||
|
Bool -> prPrec i 0 (concatD [doc (showString "boolean")])
|
||||||
|
Void -> prPrec i 0 (concatD [doc (showString "void")])
|
||||||
|
Fun type' types -> prPrec i 0 (concatD [prt 0 type' , doc (showString "(") , prt 0 types , doc (showString ")")])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[] -> (concatD [])
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print Expr where
|
||||||
|
prt i e = case e of
|
||||||
|
EVar id -> prPrec i 6 (concatD [prt 0 id])
|
||||||
|
ELitInt n -> prPrec i 6 (concatD [prt 0 n])
|
||||||
|
ELitDoub d -> prPrec i 6 (concatD [prt 0 d])
|
||||||
|
ELitTrue -> prPrec i 6 (concatD [doc (showString "true")])
|
||||||
|
ELitFalse -> prPrec i 6 (concatD [doc (showString "false")])
|
||||||
|
EApp id exprs -> prPrec i 6 (concatD [prt 0 id , doc (showString "(") , prt 0 exprs , doc (showString ")")])
|
||||||
|
EString str -> prPrec i 6 (concatD [prt 0 str])
|
||||||
|
Neg expr -> prPrec i 5 (concatD [doc (showString "-") , prt 6 expr])
|
||||||
|
Not expr -> prPrec i 5 (concatD [doc (showString "!") , prt 6 expr])
|
||||||
|
EMul expr0 mulop expr -> prPrec i 4 (concatD [prt 4 expr0 , prt 0 mulop , prt 5 expr])
|
||||||
|
EAdd expr0 addop expr -> prPrec i 3 (concatD [prt 3 expr0 , prt 0 addop , prt 4 expr])
|
||||||
|
ERel expr0 relop expr -> prPrec i 2 (concatD [prt 2 expr0 , prt 0 relop , prt 3 expr])
|
||||||
|
EAnd expr0 expr -> prPrec i 1 (concatD [prt 2 expr0 , doc (showString "&&") , prt 1 expr])
|
||||||
|
EOr expr0 expr -> prPrec i 0 (concatD [prt 1 expr0 , doc (showString "||") , prt 0 expr])
|
||||||
|
|
||||||
|
prtList es = case es of
|
||||||
|
[] -> (concatD [])
|
||||||
|
[x] -> (concatD [prt 0 x])
|
||||||
|
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
|
||||||
|
|
||||||
|
instance Print AddOp where
|
||||||
|
prt i e = case e of
|
||||||
|
Plus -> prPrec i 0 (concatD [doc (showString "+")])
|
||||||
|
Minus -> prPrec i 0 (concatD [doc (showString "-")])
|
||||||
|
|
||||||
|
|
||||||
|
instance Print MulOp where
|
||||||
|
prt i e = case e of
|
||||||
|
Times -> prPrec i 0 (concatD [doc (showString "*")])
|
||||||
|
Div -> prPrec i 0 (concatD [doc (showString "/")])
|
||||||
|
Mod -> prPrec i 0 (concatD [doc (showString "%")])
|
||||||
|
|
||||||
|
|
||||||
|
instance Print RelOp where
|
||||||
|
prt i e = case e of
|
||||||
|
LTH -> prPrec i 0 (concatD [doc (showString "<")])
|
||||||
|
LE -> prPrec i 0 (concatD [doc (showString "<=")])
|
||||||
|
GTH -> prPrec i 0 (concatD [doc (showString ">")])
|
||||||
|
GE -> prPrec i 0 (concatD [doc (showString ">=")])
|
||||||
|
EQU -> prPrec i 0 (concatD [doc (showString "==")])
|
||||||
|
NE -> prPrec i 0 (concatD [doc (showString "!=")])
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
PrintJavalette.o
Normal file
BIN
PrintJavalette.o
Normal file
Binary file not shown.
BIN
PrintUtils.class
Normal file
BIN
PrintUtils.class
Normal file
Binary file not shown.
BIN
Runtime.class
Normal file
BIN
Runtime.class
Normal file
Binary file not shown.
68
Runtime.java
Normal file
68
Runtime.java
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
class Runtime {
|
||||||
|
|
||||||
|
public static void main(String [] argv) {
|
||||||
|
Runtime.printString("Runtime test\nWrite a int: ");
|
||||||
|
|
||||||
|
int i = Runtime.readInt();
|
||||||
|
Runtime.printString("Int: ");
|
||||||
|
Runtime.printInt(i);
|
||||||
|
|
||||||
|
Runtime.printString("\nWrite a double: ");
|
||||||
|
double d = Runtime.readDouble();
|
||||||
|
Runtime.printString("Double: ");
|
||||||
|
Runtime.printDouble(d);
|
||||||
|
Runtime.printString("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printInt(int i) {
|
||||||
|
System.out.print(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printDouble(double d) {
|
||||||
|
System.out.print(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printString(String s) {
|
||||||
|
System.out.print(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int readInt() {
|
||||||
|
String line = null;
|
||||||
|
int val = 0;
|
||||||
|
try {
|
||||||
|
BufferedReader is = new BufferedReader(
|
||||||
|
new InputStreamReader(System.in));
|
||||||
|
line = is.readLine();
|
||||||
|
val = Integer.parseInt(line);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
System.err.println("Not a valid number: " + line);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Unexpected IO ERROR: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double readDouble() {
|
||||||
|
InputStreamReader convert = new InputStreamReader(System.in);
|
||||||
|
BufferedReader stdin = new BufferedReader(convert);
|
||||||
|
String instr = null;
|
||||||
|
double val = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
instr = stdin.readLine();
|
||||||
|
val = new Double(instr).doubleValue();;
|
||||||
|
} catch(NumberFormatException ex) {
|
||||||
|
System.err.println("Not a valid number: " + instr);
|
||||||
|
} catch(IOException e) {
|
||||||
|
System.err.println("Unexpected IO ERROR: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
SkelJavalette.hi
Normal file
BIN
SkelJavalette.hi
Normal file
Binary file not shown.
110
SkelJavalette.hs
Normal file
110
SkelJavalette.hs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
module SkelJavalette where
|
||||||
|
|
||||||
|
-- Haskell module generated by the BNF converter
|
||||||
|
|
||||||
|
import AbsJavalette
|
||||||
|
import ErrM
|
||||||
|
type Result = Err String
|
||||||
|
|
||||||
|
failure :: Show a => a -> Result
|
||||||
|
failure x = Bad $ "Undefined case: " ++ show x
|
||||||
|
|
||||||
|
transIdent :: Ident -> Result
|
||||||
|
transIdent x = case x of
|
||||||
|
Ident str -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transProgram :: Program -> Result
|
||||||
|
transProgram x = case x of
|
||||||
|
Program topdefs -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transTopDef :: TopDef -> Result
|
||||||
|
transTopDef x = case x of
|
||||||
|
FnDef type' id args block -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transArg :: Arg -> Result
|
||||||
|
transArg x = case x of
|
||||||
|
Arg type' id -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transBlock :: Block -> Result
|
||||||
|
transBlock x = case x of
|
||||||
|
Block stmts -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transStmt :: Stmt -> Result
|
||||||
|
transStmt x = case x of
|
||||||
|
Empty -> failure x
|
||||||
|
BStmt block -> failure x
|
||||||
|
Decl type' items -> failure x
|
||||||
|
Ass id expr -> failure x
|
||||||
|
Incr id -> failure x
|
||||||
|
Decr id -> failure x
|
||||||
|
Ret expr -> failure x
|
||||||
|
VRet -> failure x
|
||||||
|
Cond expr stmt -> failure x
|
||||||
|
CondElse expr stmt0 stmt -> failure x
|
||||||
|
While expr stmt -> failure x
|
||||||
|
SExp expr -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transItem :: Item -> Result
|
||||||
|
transItem x = case x of
|
||||||
|
NoInit id -> failure x
|
||||||
|
Init id expr -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transType :: Type -> Result
|
||||||
|
transType x = case x of
|
||||||
|
Int -> failure x
|
||||||
|
Doub -> failure x
|
||||||
|
Bool -> failure x
|
||||||
|
Void -> failure x
|
||||||
|
Fun type' types -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transExpr :: Expr -> Result
|
||||||
|
transExpr x = case x of
|
||||||
|
EVar id -> failure x
|
||||||
|
ELitInt n -> failure x
|
||||||
|
ELitDoub d -> failure x
|
||||||
|
ELitTrue -> failure x
|
||||||
|
ELitFalse -> failure x
|
||||||
|
EApp id exprs -> failure x
|
||||||
|
EString str -> failure x
|
||||||
|
Neg expr -> failure x
|
||||||
|
Not expr -> failure x
|
||||||
|
EMul expr0 mulop expr -> failure x
|
||||||
|
EAdd expr0 addop expr -> failure x
|
||||||
|
ERel expr0 relop expr -> failure x
|
||||||
|
EAnd expr0 expr -> failure x
|
||||||
|
EOr expr0 expr -> failure x
|
||||||
|
TAnot type' expr -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transAddOp :: AddOp -> Result
|
||||||
|
transAddOp x = case x of
|
||||||
|
Plus -> failure x
|
||||||
|
Minus -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transMulOp :: MulOp -> Result
|
||||||
|
transMulOp x = case x of
|
||||||
|
Times -> failure x
|
||||||
|
Div -> failure x
|
||||||
|
Mod -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transRelOp :: RelOp -> Result
|
||||||
|
transRelOp x = case x of
|
||||||
|
LTH -> failure x
|
||||||
|
LE -> failure x
|
||||||
|
GTH -> failure x
|
||||||
|
GE -> failure x
|
||||||
|
EQU -> failure x
|
||||||
|
NE -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
|
109
SkelJavalette.hs.bak
Normal file
109
SkelJavalette.hs.bak
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
module SkelJavalette where
|
||||||
|
|
||||||
|
-- Haskell module generated by the BNF converter
|
||||||
|
|
||||||
|
import AbsJavalette
|
||||||
|
import ErrM
|
||||||
|
type Result = Err String
|
||||||
|
|
||||||
|
failure :: Show a => a -> Result
|
||||||
|
failure x = Bad $ "Undefined case: " ++ show x
|
||||||
|
|
||||||
|
transIdent :: Ident -> Result
|
||||||
|
transIdent x = case x of
|
||||||
|
Ident str -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transProgram :: Program -> Result
|
||||||
|
transProgram x = case x of
|
||||||
|
Program topdefs -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transTopDef :: TopDef -> Result
|
||||||
|
transTopDef x = case x of
|
||||||
|
FnDef type' id args block -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transArg :: Arg -> Result
|
||||||
|
transArg x = case x of
|
||||||
|
Arg type' id -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transBlock :: Block -> Result
|
||||||
|
transBlock x = case x of
|
||||||
|
Block stmts -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transStmt :: Stmt -> Result
|
||||||
|
transStmt x = case x of
|
||||||
|
Empty -> failure x
|
||||||
|
BStmt block -> failure x
|
||||||
|
Decl type' items -> failure x
|
||||||
|
Ass id expr -> failure x
|
||||||
|
Incr id -> failure x
|
||||||
|
Decr id -> failure x
|
||||||
|
Ret expr -> failure x
|
||||||
|
VRet -> failure x
|
||||||
|
Cond expr stmt -> failure x
|
||||||
|
CondElse expr stmt0 stmt -> failure x
|
||||||
|
While expr stmt -> failure x
|
||||||
|
SExp expr -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transItem :: Item -> Result
|
||||||
|
transItem x = case x of
|
||||||
|
NoInit id -> failure x
|
||||||
|
Init id expr -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transType :: Type -> Result
|
||||||
|
transType x = case x of
|
||||||
|
Int -> failure x
|
||||||
|
Doub -> failure x
|
||||||
|
Bool -> failure x
|
||||||
|
Void -> failure x
|
||||||
|
Fun type' types -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transExpr :: Expr -> Result
|
||||||
|
transExpr x = case x of
|
||||||
|
EVar id -> failure x
|
||||||
|
ELitInt n -> failure x
|
||||||
|
ELitDoub d -> failure x
|
||||||
|
ELitTrue -> failure x
|
||||||
|
ELitFalse -> failure x
|
||||||
|
EApp id exprs -> failure x
|
||||||
|
EString str -> failure x
|
||||||
|
Neg expr -> failure x
|
||||||
|
Not expr -> failure x
|
||||||
|
EMul expr0 mulop expr -> failure x
|
||||||
|
EAdd expr0 addop expr -> failure x
|
||||||
|
ERel expr0 relop expr -> failure x
|
||||||
|
EAnd expr0 expr -> failure x
|
||||||
|
EOr expr0 expr -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transAddOp :: AddOp -> Result
|
||||||
|
transAddOp x = case x of
|
||||||
|
Plus -> failure x
|
||||||
|
Minus -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transMulOp :: MulOp -> Result
|
||||||
|
transMulOp x = case x of
|
||||||
|
Times -> failure x
|
||||||
|
Div -> failure x
|
||||||
|
Mod -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
transRelOp :: RelOp -> Result
|
||||||
|
transRelOp x = case x of
|
||||||
|
LTH -> failure x
|
||||||
|
LE -> failure x
|
||||||
|
GTH -> failure x
|
||||||
|
GE -> failure x
|
||||||
|
EQU -> failure x
|
||||||
|
NE -> failure x
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
SkelJavalette.o
Normal file
BIN
SkelJavalette.o
Normal file
Binary file not shown.
BIN
TestJavalette
Executable file
BIN
TestJavalette
Executable file
Binary file not shown.
BIN
TestJavalette.hi
Normal file
BIN
TestJavalette.hi
Normal file
Binary file not shown.
58
TestJavalette.hs
Normal file
58
TestJavalette.hs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
-- automatically generated by BNF Converter
|
||||||
|
module Main where
|
||||||
|
|
||||||
|
|
||||||
|
import IO ( stdin, hGetContents )
|
||||||
|
import System ( getArgs, getProgName )
|
||||||
|
|
||||||
|
import LexJavalette
|
||||||
|
import ParJavalette
|
||||||
|
import SkelJavalette
|
||||||
|
import PrintJavalette
|
||||||
|
import AbsJavalette
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import ErrM
|
||||||
|
|
||||||
|
type ParseFun a = [Token] -> Err a
|
||||||
|
|
||||||
|
myLLexer = myLexer
|
||||||
|
|
||||||
|
type Verbosity = Int
|
||||||
|
|
||||||
|
putStrV :: Verbosity -> String -> IO ()
|
||||||
|
putStrV v s = if v > 1 then putStrLn s else return ()
|
||||||
|
|
||||||
|
runFile :: (Print a, Show a) => Verbosity -> ParseFun a -> FilePath -> IO ()
|
||||||
|
runFile v p f = putStrLn f >> readFile f >>= run v p
|
||||||
|
|
||||||
|
run :: (Print a, Show a) => Verbosity -> ParseFun a -> String -> IO ()
|
||||||
|
run v p s = let ts = myLLexer s in case p ts of
|
||||||
|
Bad s -> do putStrLn "\nParse Failed...\n"
|
||||||
|
putStrV v "Tokens:"
|
||||||
|
putStrV v $ show ts
|
||||||
|
putStrLn s
|
||||||
|
Ok tree -> do putStrLn "\nParse Successful!"
|
||||||
|
showTree v tree
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
showTree :: (Show a, Print a) => Int -> a -> IO ()
|
||||||
|
showTree v tree
|
||||||
|
= do
|
||||||
|
putStrV v $ "\n[Abstract Syntax]\n\n" ++ show tree
|
||||||
|
putStrV v $ "\n[Linearized tree]\n\n" ++ printTree tree
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do args <- getArgs
|
||||||
|
case args of
|
||||||
|
[] -> hGetContents stdin >>= run 2 pProgram
|
||||||
|
"-s":fs -> mapM_ (runFile 0 pProgram) fs
|
||||||
|
fs -> mapM_ (runFile 2 pProgram) fs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
58
TestJavalette.hs.bak
Normal file
58
TestJavalette.hs.bak
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
-- automatically generated by BNF Converter
|
||||||
|
module Main where
|
||||||
|
|
||||||
|
|
||||||
|
import IO ( stdin, hGetContents )
|
||||||
|
import System ( getArgs, getProgName )
|
||||||
|
|
||||||
|
import LexJavalette
|
||||||
|
import ParJavalette
|
||||||
|
import SkelJavalette
|
||||||
|
import PrintJavalette
|
||||||
|
import AbsJavalette
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import ErrM
|
||||||
|
|
||||||
|
type ParseFun a = [Token] -> Err a
|
||||||
|
|
||||||
|
myLLexer = myLexer
|
||||||
|
|
||||||
|
type Verbosity = Int
|
||||||
|
|
||||||
|
putStrV :: Verbosity -> String -> IO ()
|
||||||
|
putStrV v s = if v > 1 then putStrLn s else return ()
|
||||||
|
|
||||||
|
runFile :: (Print a, Show a) => Verbosity -> ParseFun a -> FilePath -> IO ()
|
||||||
|
runFile v p f = putStrLn f >> readFile f >>= run v p
|
||||||
|
|
||||||
|
run :: (Print a, Show a) => Verbosity -> ParseFun a -> String -> IO ()
|
||||||
|
run v p s = let ts = myLLexer s in case p ts of
|
||||||
|
Bad s -> do putStrLn "\nParse Failed...\n"
|
||||||
|
putStrV v "Tokens:"
|
||||||
|
putStrV v $ show ts
|
||||||
|
putStrLn s
|
||||||
|
Ok tree -> do putStrLn "\nParse Successful!"
|
||||||
|
showTree v tree
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
showTree :: (Show a, Print a) => Int -> a -> IO ()
|
||||||
|
showTree v tree
|
||||||
|
= do
|
||||||
|
putStrV v $ "\n[Abstract Syntax]\n\n" ++ show tree
|
||||||
|
putStrV v $ "\n[Linearized tree]\n\n" ++ printTree tree
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do args <- getArgs
|
||||||
|
case args of
|
||||||
|
[] -> hGetContents stdin >>= run 2 pProgram
|
||||||
|
"-s":fs -> mapM_ (runFile 0 pProgram) fs
|
||||||
|
fs -> mapM_ (runFile 2 pProgram) fs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
TestJavalette.o
Normal file
BIN
TestJavalette.o
Normal file
Binary file not shown.
BIN
TypeChecker.hi
Normal file
BIN
TypeChecker.hi
Normal file
Binary file not shown.
321
TypeChecker.hs
Normal file
321
TypeChecker.hs
Normal file
|
@ -0,0 +1,321 @@
|
||||||
|
module TypeChecker where
|
||||||
|
|
||||||
|
import Debug.Trace
|
||||||
|
import AbsJavalette
|
||||||
|
import PrintJavalette
|
||||||
|
import ErrM
|
||||||
|
import Control.Monad.State
|
||||||
|
import Data.List
|
||||||
|
|
||||||
|
type AnotTree = [TopDef]
|
||||||
|
type Errors = [String]
|
||||||
|
type Env = [[(Ident, Type)]]
|
||||||
|
type MyState = (Env, AnotTree, Errors)
|
||||||
|
type MyStateM = State MyState
|
||||||
|
|
||||||
|
|
||||||
|
typecheck :: Program -> Err Program
|
||||||
|
typecheck (Program fs) = do let (at, err) = evalState (checkFuncs fs >> checkProgram fs >> getAnotTree) emptyState
|
||||||
|
if err == []
|
||||||
|
then return (Program at)
|
||||||
|
else fail $ printTree at ++ (show err)
|
||||||
|
|
||||||
|
getAnotTree :: MyStateM (AnotTree, Errors)
|
||||||
|
getAnotTree = do (_, at, e) <- get
|
||||||
|
return (at, e)
|
||||||
|
|
||||||
|
checkFuncs :: [TopDef] -> MyStateM ()
|
||||||
|
checkFuncs [] = return ()
|
||||||
|
checkFuncs (f@(FnDef t i a (Block s)):fs) = do (env, at, err) <- get
|
||||||
|
case find (\(ident, _) -> ident == i) (concat env) of
|
||||||
|
-- TODO: check if args already in scope
|
||||||
|
Nothing -> do let args = [t | (Arg t _) <- a]
|
||||||
|
let newEnv = [(i, (Fun t args))]:env
|
||||||
|
put (newEnv, at, err)
|
||||||
|
checkFuncs fs
|
||||||
|
Just _ -> do addErr (show i ++ " already in scope")
|
||||||
|
checkFuncs fs
|
||||||
|
|
||||||
|
|
||||||
|
checkProgram :: [TopDef] -> MyStateM ()
|
||||||
|
checkProgram [] = return ()
|
||||||
|
checkProgram (f:fs) = do checkFun f
|
||||||
|
checkProgram fs
|
||||||
|
|
||||||
|
checkFun :: TopDef -> MyStateM ()
|
||||||
|
checkFun (FnDef t i a (Block s)) = do pushFunScope a
|
||||||
|
ns <- checkStmts s [] t
|
||||||
|
popFunScope
|
||||||
|
b <- addArgs a []
|
||||||
|
(env, at, err) <- get
|
||||||
|
let newAt = at ++ [(FnDef t i b (Block ns))]
|
||||||
|
put (env, newAt, err)
|
||||||
|
return ()
|
||||||
|
|
||||||
|
checkStmts :: [Stmt] -> [Stmt] -> Type -> MyStateM [Stmt]
|
||||||
|
checkStmts [] nss rt = return nss
|
||||||
|
checkStmts (s:ss) nss rt = do ns <- checkStmt s rt
|
||||||
|
checkStmts ss (nss ++ [ns]) rt
|
||||||
|
|
||||||
|
checkStmt :: Stmt -> Type -> MyStateM Stmt
|
||||||
|
checkStmt s rt = case s of
|
||||||
|
|
||||||
|
BStmt (Block s) -> do pushBlockScope
|
||||||
|
ns <- checkStmts s [] rt
|
||||||
|
popBlockScope
|
||||||
|
return (BStmt (Block ns))
|
||||||
|
|
||||||
|
Decl t vars -> do nvars <- addVars t vars []
|
||||||
|
return (Decl t nvars)
|
||||||
|
|
||||||
|
Ass i e -> do vt <- findVarType i
|
||||||
|
(TAnot et ne) <- infer e
|
||||||
|
case vt of
|
||||||
|
Just t -> case t == et of
|
||||||
|
True -> return (Ass i (TAnot et ne))
|
||||||
|
False -> do addErr (show e ++ " is not of the type " ++
|
||||||
|
show t ++ " (" ++ show i ++ ")")
|
||||||
|
return (Ass i (TAnot et ne))
|
||||||
|
Nothing -> return (Ass i e)
|
||||||
|
|
||||||
|
|
||||||
|
Incr i -> do m <- findVarType i
|
||||||
|
case m of
|
||||||
|
Just Int -> return (Incr i)
|
||||||
|
Just Doub -> return (Incr i)
|
||||||
|
Just t -> do addErr ("(" ++ show i ++
|
||||||
|
") incrementing is only allowed on Int " ++
|
||||||
|
"and Doub, not on " ++
|
||||||
|
show t)
|
||||||
|
return (Incr i)
|
||||||
|
Nothing -> do addErr ("(" ++ show i ++ ") incrementing is only " ++
|
||||||
|
"allowed on Int and Doub")
|
||||||
|
return (Incr i)
|
||||||
|
|
||||||
|
Decr i -> do m <- findVarType i
|
||||||
|
case m of
|
||||||
|
Just Int -> return (Decr i)
|
||||||
|
Just Doub -> return (Decr i)
|
||||||
|
Just t -> do addErr ("(" ++ show i ++
|
||||||
|
") decrementing is only allowed on Int " ++
|
||||||
|
"and Doub, not on " ++
|
||||||
|
show t)
|
||||||
|
return (Decr i)
|
||||||
|
Nothing -> do addErr ("(" ++ show i ++ ") decrementing is only " ++
|
||||||
|
"allowed on Int and Doub")
|
||||||
|
return (Decr i)
|
||||||
|
|
||||||
|
Ret e -> do m <- infer e
|
||||||
|
case m of
|
||||||
|
(TAnot t ne) -> case t == rt of
|
||||||
|
True -> return (Ret m)
|
||||||
|
False -> do addErr (show "wrong return type " ++ show t ++
|
||||||
|
" should be " ++ show rt)
|
||||||
|
return (Ret m)
|
||||||
|
_ -> do addErr (show e ++ " return not annotated")
|
||||||
|
return (Ret m)
|
||||||
|
-- TODO check if it returns the right type
|
||||||
|
|
||||||
|
VRet -> return VRet
|
||||||
|
|
||||||
|
Cond e stm -> do m <- infer e
|
||||||
|
ns <- checkStmt stm rt
|
||||||
|
return (Cond m ns)
|
||||||
|
|
||||||
|
CondElse e s1 s2 -> do m <- infer e
|
||||||
|
ns1 <- checkStmt s1 rt
|
||||||
|
ns2 <- checkStmt s2 rt
|
||||||
|
return (CondElse m ns1 ns2)
|
||||||
|
|
||||||
|
While e stm -> do m <- infer e
|
||||||
|
ns <- checkStmt stm rt
|
||||||
|
return (While m ns)
|
||||||
|
|
||||||
|
SExp e -> do m <- infer e
|
||||||
|
return (SExp m)
|
||||||
|
s -> do addErr "Not an valid statement"
|
||||||
|
return s
|
||||||
|
|
||||||
|
addArgs :: [Arg] -> [Arg] -> MyStateM ([Arg])
|
||||||
|
addArgs [] nass = return (nass)
|
||||||
|
addArgs ((Arg t i):ass) nass = do ((e:env), at, err) <- get
|
||||||
|
case (find (\(ident, nt) -> ident == i) e) of
|
||||||
|
Nothing -> do let newEnv = ((i, t):e):env
|
||||||
|
put(trace (show newEnv) newEnv, at, err)
|
||||||
|
addArgs ass ((Arg t i):nass)
|
||||||
|
Just ident -> do addErr (show ident ++ " already in scope")
|
||||||
|
addArgs ass ((Arg t i):nass)
|
||||||
|
|
||||||
|
|
||||||
|
addVars :: Type -> [Item] -> [Item] -> MyStateM ([Item])
|
||||||
|
addVars t [] nis = return (nis)
|
||||||
|
addVars t ((NoInit i):is) nis = do ((e:env), at, err) <- get
|
||||||
|
case (find (\(ident, nt) -> ident == i) e) of
|
||||||
|
Nothing -> do let newEnv = ((i, t):e):env
|
||||||
|
put (newEnv, at, err)
|
||||||
|
addVars t is (nis ++ [(NoInit i)])
|
||||||
|
Just ident -> do addErr (show ident ++ " already initialized")
|
||||||
|
addVars t is (nis ++ [(NoInit i)])
|
||||||
|
addVars t ((Init i ex):is) nis = do (TAnot nt ne) <- infer ex
|
||||||
|
case t == nt of
|
||||||
|
True -> do ((e:env), at, err) <- get
|
||||||
|
case (find (\(ident, nt) -> ident == i) e) of
|
||||||
|
Nothing -> do let newEnv = ((i, t):e):env
|
||||||
|
put (newEnv, at, err)
|
||||||
|
addVars t is (nis ++ [(Init i (TAnot nt ne))])
|
||||||
|
Just ident -> do addErr (show ident ++ " already initialized")
|
||||||
|
addVars t is (nis ++ [(Init i (TAnot nt ne))])
|
||||||
|
False -> do addErr (show ex ++ " is not of type " ++ show t)
|
||||||
|
((e:env), at, err) <- get
|
||||||
|
let newEnv = ((i, t):e):env
|
||||||
|
put (newEnv, at, err)
|
||||||
|
addVars t is (nis ++ [(Init i ex)])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
infer :: Expr -> MyStateM Expr
|
||||||
|
infer expr = case expr of
|
||||||
|
EVar i -> do m <- findVarType i
|
||||||
|
case m of
|
||||||
|
Just t -> return (TAnot t (EVar i))
|
||||||
|
Nothing -> return (EVar i)
|
||||||
|
|
||||||
|
ELitInt e -> return (TAnot Int (ELitInt e))
|
||||||
|
ELitDoub e -> return (TAnot Doub (ELitDoub e))
|
||||||
|
ELitTrue -> return (TAnot Bool ELitTrue)
|
||||||
|
ELitFalse -> return (TAnot Bool ELitFalse)
|
||||||
|
EApp i exs -> do m <- findVarType i
|
||||||
|
nexs <- inferList exs []
|
||||||
|
case m of
|
||||||
|
Just (Fun t a) -> case ((length nexs) == (length a)) of
|
||||||
|
True -> case (and [t1 == t2 | ((TAnot t1 _),t2) <- zip nexs a]) of
|
||||||
|
True -> return (TAnot t (EApp i nexs))
|
||||||
|
False -> do addErr (show i ++ ":s arguments (" ++
|
||||||
|
show nexs ++ ") are not equal to " ++
|
||||||
|
show a)
|
||||||
|
return (TAnot t (EApp i nexs))
|
||||||
|
False -> case i of
|
||||||
|
Ident "printString" -> case exs of
|
||||||
|
[EString _] -> return (EApp i exs)
|
||||||
|
_ -> do addErr ("printString only takes one literal string as a argument")
|
||||||
|
return (EApp i exs)
|
||||||
|
_ -> do addErr ("wrong number of arguments for " ++ show i)
|
||||||
|
return (TAnot t (EApp i nexs))
|
||||||
|
|
||||||
|
Nothing -> do addErr ("wrong arguments in " ++ show i)
|
||||||
|
return (EApp i exs) -- TODO: check for Nothing or other
|
||||||
|
|
||||||
|
|
||||||
|
EString e -> return (EString e)
|
||||||
|
Neg e -> do m <- infer e
|
||||||
|
case m of
|
||||||
|
(TAnot Int _) -> return (TAnot Int (Neg m))
|
||||||
|
(TAnot Doub _) -> return (TAnot Doub (Neg m))
|
||||||
|
_ -> do addErr (show e ++ " is not of type Int or Bool")
|
||||||
|
return (Neg e)
|
||||||
|
Not e -> do m <- infer e
|
||||||
|
case m of
|
||||||
|
(TAnot Bool _) -> return (TAnot Bool (Not m))
|
||||||
|
_ -> do addErr (show e ++ " is not of type Bool")
|
||||||
|
return (Not e)
|
||||||
|
|
||||||
|
EMul e1 op e2 -> do t <- findType e1 e2 [Int, Doub]
|
||||||
|
case t of
|
||||||
|
Just (Int, en1, en2) -> return (TAnot Int (EMul en1 op en2))
|
||||||
|
Just (Doub, en1, en2) -> return (TAnot Doub (EMul en1 op en2))
|
||||||
|
Nothing -> return (EMul e1 op e2)
|
||||||
|
|
||||||
|
EAdd e1 op e2 -> do t <- findType e1 e2 [Int, Doub]
|
||||||
|
case t of
|
||||||
|
Just (Int, en1, en2) -> return (TAnot Int (EAdd en1 op en2))
|
||||||
|
Just (Doub, en1, en2) -> return (TAnot Doub (EAdd en1 op en2))
|
||||||
|
Nothing -> return (EAdd e1 op e2)
|
||||||
|
|
||||||
|
ERel e1 op e2 -> case find (== op) [LTH,LE,GTH,GE] of
|
||||||
|
Just _ -> do t <- findType e1 e2 [Int, Doub]
|
||||||
|
case t of
|
||||||
|
Just (Int, en1, en2) -> return (TAnot Bool (ERel en1 op en2))
|
||||||
|
Just (Doub, en1, en2) -> return (TAnot Bool (ERel en1 op en2))
|
||||||
|
Nothing -> return (ERel e1 op e2)
|
||||||
|
|
||||||
|
Nothing -> do m <- findType e1 e2 [Int, Doub, Bool]
|
||||||
|
case m of
|
||||||
|
Just (_, en1, en2) -> return (TAnot Bool (ERel en1 op en2))
|
||||||
|
Nothing -> return (ERel e1 op e2)
|
||||||
|
|
||||||
|
EAnd e1 e2 -> do t <- findType e1 e2 [Bool]
|
||||||
|
case t of
|
||||||
|
Just (Bool, en1, en2) -> return (TAnot Bool (EAnd en1 en2))
|
||||||
|
Nothing -> return (EAnd e1 e2)
|
||||||
|
|
||||||
|
EOr e1 e2 -> do t <- findType e1 e2 [Bool]
|
||||||
|
case t of
|
||||||
|
Just (Bool, en1, en2) -> return (TAnot Bool (EOr en1 en2))
|
||||||
|
Nothing -> return (EOr e1 e2)
|
||||||
|
|
||||||
|
inferList :: [Expr] -> [Expr] -> MyStateM [Expr]
|
||||||
|
inferList [] nes = return nes
|
||||||
|
inferList (e:es) nes = do ne <- infer e
|
||||||
|
inferList es (nes ++ [ne])
|
||||||
|
|
||||||
|
findType :: Expr -> Expr -> [Type] -> MyStateM (Maybe (Type, Expr, Expr))
|
||||||
|
findType e1 e2 allowed = do t1 <- infer e1
|
||||||
|
t2 <- infer e2
|
||||||
|
let (TAnot tt1 _) = t1
|
||||||
|
let (TAnot tt2 _) = t2
|
||||||
|
case tt1 == tt2 of
|
||||||
|
True -> case t1 of
|
||||||
|
(TAnot t _) -> case (find (== t) allowed) of
|
||||||
|
Just _ -> return (Just (t, t1, t2))
|
||||||
|
Nothing -> do addErr (show t ++
|
||||||
|
" is not allowed here")
|
||||||
|
return Nothing
|
||||||
|
_ -> return Nothing
|
||||||
|
False -> do addErr (show e1 ++ " and " ++ show e2 ++ " are not of type " ++ show t1)
|
||||||
|
return Nothing
|
||||||
|
|
||||||
|
findVarType :: Ident -> MyStateM (Maybe Type)
|
||||||
|
findVarType var = do (env, at, err) <- get
|
||||||
|
let m = find (\(i, t) -> i == var) (concat env)
|
||||||
|
case m of
|
||||||
|
Just t -> return (Just (snd t))
|
||||||
|
Nothing -> do addErr ((show var) ++ " not in scope")
|
||||||
|
return Nothing
|
||||||
|
|
||||||
|
|
||||||
|
-- initializing functions
|
||||||
|
emptyState :: MyState
|
||||||
|
emptyState = (emptyEnv, [], [])
|
||||||
|
|
||||||
|
emptyEnv :: Env
|
||||||
|
emptyEnv = [[
|
||||||
|
(Ident "printString", (Fun Void [])),
|
||||||
|
(Ident "printDouble", (Fun Void [Doub])),
|
||||||
|
(Ident "printInt", (Fun Void [Int])),
|
||||||
|
(Ident "readDouble", (Fun Doub [])),
|
||||||
|
(Ident "readInt", (Fun Int []))
|
||||||
|
]]
|
||||||
|
|
||||||
|
-- helper functions
|
||||||
|
pushFunScope :: [Arg] -> MyStateM ()
|
||||||
|
pushFunScope a = do (env, at, err) <- get
|
||||||
|
let args = [(i,t) | (Arg t i) <- a]
|
||||||
|
put (args:env, at, err)
|
||||||
|
return ()
|
||||||
|
|
||||||
|
popFunScope :: MyStateM ()
|
||||||
|
popFunScope = do (env, at, err) <- get
|
||||||
|
put (tail env, at, err)
|
||||||
|
return ()
|
||||||
|
|
||||||
|
pushBlockScope :: MyStateM ()
|
||||||
|
pushBlockScope = pushFunScope []
|
||||||
|
|
||||||
|
popBlockScope :: MyStateM ()
|
||||||
|
popBlockScope = popFunScope
|
||||||
|
|
||||||
|
addErr :: String -> MyStateM ()
|
||||||
|
addErr err = do (env, at, errs) <- get
|
||||||
|
put (env, at, err:errs)
|
||||||
|
return ()
|
||||||
|
|
8
TypeChecker.hs~
Normal file
8
TypeChecker.hs~
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module TypeChecker where
|
||||||
|
|
||||||
|
import AbsJavalette
|
||||||
|
import PrintJavalette
|
||||||
|
import ErrM
|
||||||
|
|
||||||
|
typecheck :: Program -> Err()
|
||||||
|
typecheck (Program fs) = fail printTree fs
|
BIN
TypeChecker.o
Normal file
BIN
TypeChecker.o
Normal file
Binary file not shown.
BIN
bnfc
Executable file
BIN
bnfc
Executable file
Binary file not shown.
BIN
jasmin/jasmin-2.4.zip
Normal file
BIN
jasmin/jasmin-2.4.zip
Normal file
Binary file not shown.
116
jasmin/jasmin-2.4/Readme.txt
Normal file
116
jasmin/jasmin-2.4/Readme.txt
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
Jasmin README file 1 March 1997, Jonathan Meyer
|
||||||
|
Last updated October 2004
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
Welcome to Jasmin version 1.1.
|
||||||
|
|
||||||
|
Jasmin is a Java Assembler Interface. It takes ASCII descriptions for Java
|
||||||
|
classes, written in a simple assembler-like syntax, using the Java
|
||||||
|
Virtual Machine instruction set. It converts them into binary Java class
|
||||||
|
files suitable for loading into a Java interpreter.
|
||||||
|
|
||||||
|
Jasmin was originally written as the companion to the
|
||||||
|
book "Java Virtual Machine", published by O'Reilly, written by
|
||||||
|
Jon Meyer and Troy Downing. (See http://www.ora.com/catalog/javavm/).
|
||||||
|
The book is now out of print. However, the Jasmin assembler retains its
|
||||||
|
usefulness as a utility, and continues its life as an OpenSource project.
|
||||||
|
|
||||||
|
Background
|
||||||
|
----------
|
||||||
|
Jasmin is today a little long in the tooth. It was originally coded in
|
||||||
|
1996 as a stop-gap until Sun released their own assembler. It has seen
|
||||||
|
no major upgrades since 1997. By 2004 Sun still has not released an
|
||||||
|
official assembler, so I decided to release Jasmin as a sourceforge
|
||||||
|
project. Hopefully this will inject some fresh life into the project...
|
||||||
|
|
||||||
|
Home Page
|
||||||
|
---------
|
||||||
|
Check out the Jasmin home page at:
|
||||||
|
|
||||||
|
http://jasmin.sourceforge.net
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
Jasmin is written in Java, and should work with most Java 1.1 environments.
|
||||||
|
|
||||||
|
To run Jasmin you need to have a Java 2 Runtime Environment available (e.g. JDK 1.4).
|
||||||
|
This can be downloaded from "http://www.javasoft.com/j2se/".
|
||||||
|
|
||||||
|
Getting Started
|
||||||
|
---------------
|
||||||
|
The Jasmin distribution contains a jasmin.jar file holding the Jasmin assembler.
|
||||||
|
To run Jasmin, execute the Jarfile, specifying any files to assemble
|
||||||
|
as command-line parameters, e.g. to assemble the "HelloWorld.j" file in examples,
|
||||||
|
first use cd to change into the Jasmin directory:
|
||||||
|
|
||||||
|
cd c:\jasmin-1.1 [Windows]
|
||||||
|
or
|
||||||
|
cd ~/jasmin-1.1 [Unix]
|
||||||
|
|
||||||
|
Then, to run Jasmin, use:
|
||||||
|
|
||||||
|
java -jar jasmin.jar examples\HelloWorld.j [Windows]
|
||||||
|
or
|
||||||
|
java -jar jasmin.jar examples/HelloWorld.j [Unix/MacOsX]
|
||||||
|
|
||||||
|
|
||||||
|
After running Jasmin as above, it generates a compiled HelloWorld.class file
|
||||||
|
in the examples directory.
|
||||||
|
|
||||||
|
You can then run the HelloWorld program by doing:
|
||||||
|
|
||||||
|
java examples.HelloWorld
|
||||||
|
|
||||||
|
Build Instructions
|
||||||
|
------------------
|
||||||
|
Jasmin uses Ant as its build mechanism. See build.xml for instructions on how
|
||||||
|
to build Jasmin. In brief, you need to:
|
||||||
|
|
||||||
|
1. Start a Terminal or Command window.
|
||||||
|
2. Change (cd) into the Jasmin directory
|
||||||
|
3. Make sure that java, javac etc. are on your path
|
||||||
|
4. Run build.bat (Windows) or build.sh (Unix).
|
||||||
|
|
||||||
|
For example, on Windows, this might look something like:
|
||||||
|
|
||||||
|
cd c:\jasmin-1.1 # change to Jasmin directory
|
||||||
|
build all
|
||||||
|
|
||||||
|
Or, for Unix, it might be like:
|
||||||
|
|
||||||
|
cd ~/jasmin-1.1 # change to Jasmin directory
|
||||||
|
./build.sh all
|
||||||
|
|
||||||
|
These scripts use the build.xml configuration file to specify build parameters.
|
||||||
|
|
||||||
|
Where Next
|
||||||
|
----------
|
||||||
|
After trying Jasmin out, have a look at the HelloWorld.j source in the examples directory,
|
||||||
|
try compiling and running the other examples.
|
||||||
|
|
||||||
|
There is documentation for Jasmin in the doc directory. You should probably
|
||||||
|
start with the 'guide.html' document.
|
||||||
|
|
||||||
|
Files
|
||||||
|
-----
|
||||||
|
The following files are included in this distribution:
|
||||||
|
|
||||||
|
README.txt - this file
|
||||||
|
jasmin.jar - executable Jar file containing Jasmin assembler
|
||||||
|
examples/ - directory containing example files written for Jasmin
|
||||||
|
src/ - the Java source code and for the jasmin package
|
||||||
|
lib/ - Contains Java sources for the java_cup and jas packages
|
||||||
|
docs/ - various documentation files.
|
||||||
|
|
||||||
|
Copyright
|
||||||
|
---------
|
||||||
|
Jasmin is Copyright (1997-2004) Jonathan Meyer, under the terms of
|
||||||
|
the GNU General Public License. See license-jasmin.txt for more.
|
||||||
|
|
||||||
|
Jasmin uses the JAS package which has its own copyright - see lib/jas/README.
|
||||||
|
[sbktech.org no longer seem to be in existence, but the code lives
|
||||||
|
on in this project].
|
||||||
|
|
||||||
|
Jasmin utilizes Scott E. Hudson's Java Cup package v0.9e, which is also in
|
||||||
|
the lib directory. See http://www.cs.princeton.edu/~appel/modern/java/CUP/
|
107
jasmin/jasmin-2.4/build.bat
Normal file
107
jasmin/jasmin-2.4/build.bat
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
REM Copyright 2001,2004 The Apache Software Foundation
|
||||||
|
REM
|
||||||
|
REM Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
REM you may not use this file except in compliance with the License.
|
||||||
|
REM You may obtain a copy of the License at
|
||||||
|
REM
|
||||||
|
REM http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
REM
|
||||||
|
REM Unless required by applicable law or agreed to in writing, software
|
||||||
|
REM distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
REM See the License for the specific language governing permissions and
|
||||||
|
REM limitations under the License.
|
||||||
|
|
||||||
|
if exist "%HOME%\antrc_pre.bat" call "%HOME%\antrc_pre.bat"
|
||||||
|
|
||||||
|
if "%OS%"=="Windows_NT" @setlocal
|
||||||
|
|
||||||
|
rem %~dp0 is expanded pathname of the current script under NT
|
||||||
|
set ANT_HOME=.
|
||||||
|
rem set DEFAULT_ANT_HOME=%~dp0..
|
||||||
|
|
||||||
|
if "%ANT_HOME%"=="" set ANT_HOME=%DEFAULT_ANT_HOME%
|
||||||
|
set DEFAULT_ANT_HOME=
|
||||||
|
|
||||||
|
rem Slurp the command line arguments. This loop allows for an unlimited number
|
||||||
|
rem of arguments (up to the command line limit, anyway).
|
||||||
|
set ANT_CMD_LINE_ARGS=%1
|
||||||
|
if ""%1""=="""" goto doneStart
|
||||||
|
shift
|
||||||
|
:setupArgs
|
||||||
|
if ""%1""=="""" goto doneStart
|
||||||
|
set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1
|
||||||
|
shift
|
||||||
|
goto setupArgs
|
||||||
|
rem This label provides a place for the argument list loop to break out
|
||||||
|
rem and for NT handling to skip to.
|
||||||
|
|
||||||
|
:doneStart
|
||||||
|
rem find ANT_HOME if it does not exist due to either an invalid value passed
|
||||||
|
rem by the user or the %0 problem on Windows 9x
|
||||||
|
if exist "%ANT_HOME%\lib\ant.jar" goto checkJava
|
||||||
|
|
||||||
|
rem check for ant in Program Files
|
||||||
|
if not exist "%ProgramFiles%\ant" goto checkSystemDrive
|
||||||
|
set ANT_HOME=%ProgramFiles%\ant
|
||||||
|
goto checkJava
|
||||||
|
|
||||||
|
:checkSystemDrive
|
||||||
|
rem check for ant in root directory of system drive
|
||||||
|
if not exist %SystemDrive%\ant\lib\ant.jar goto checkCDrive
|
||||||
|
set ANT_HOME=%SystemDrive%\ant
|
||||||
|
goto checkJava
|
||||||
|
|
||||||
|
:checkCDrive
|
||||||
|
rem check for ant in C:\ant for Win9X users
|
||||||
|
if not exist C:\ant\lib\ant.jar goto noAntHome
|
||||||
|
set ANT_HOME=C:\ant
|
||||||
|
goto checkJava
|
||||||
|
|
||||||
|
:noAntHome
|
||||||
|
echo ANT_HOME is set incorrectly or ant could not be located. Please set ANT_HOME.
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:checkJava
|
||||||
|
set _JAVACMD=%JAVACMD%
|
||||||
|
|
||||||
|
if "%JAVA_HOME%" == "" goto noJavaHome
|
||||||
|
if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
|
||||||
|
if "%_JAVACMD%" == "" set _JAVACMD=%JAVA_HOME%\bin\java.exe
|
||||||
|
goto checkJikes
|
||||||
|
|
||||||
|
:noJavaHome
|
||||||
|
if "%_JAVACMD%" == "" set _JAVACMD=java.exe
|
||||||
|
|
||||||
|
:checkJikes
|
||||||
|
if not "%JIKESPATH%"=="" goto runAntWithJikes
|
||||||
|
|
||||||
|
:runAnt
|
||||||
|
if not "%CLASSPATH%"=="" goto runAntWithClasspath
|
||||||
|
"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS%
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:runAntWithClasspath
|
||||||
|
"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -lib "%CLASSPATH%" %ANT_CMD_LINE_ARGS%
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:runAntWithJikes
|
||||||
|
if not "%CLASSPATH%"=="" goto runAntWithJikesAndClasspath
|
||||||
|
"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS%
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:runAntWithJikesAndClasspath
|
||||||
|
"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -lib "%CLASSPATH%" %ANT_CMD_LINE_ARGS%
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:end
|
||||||
|
set _JAVACMD=
|
||||||
|
set ANT_CMD_LINE_ARGS=
|
||||||
|
|
||||||
|
if "%OS%"=="Windows_NT" @endlocal
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if exist "%HOME%\antrc_post.bat" call "%HOME%\antrc_post.bat"
|
||||||
|
|
305
jasmin/jasmin-2.4/build.sh
Normal file
305
jasmin/jasmin-2.4/build.sh
Normal file
|
@ -0,0 +1,305 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
# Copyright 2001-2004 The Apache Software Foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
ANT_HOME=.
|
||||||
|
export ANT_HOME
|
||||||
|
|
||||||
|
# Extract launch and ant arguments, (see details below).
|
||||||
|
ant_exec_args=
|
||||||
|
no_config=false
|
||||||
|
use_jikes_default=false
|
||||||
|
ant_exec_debug=false
|
||||||
|
show_help=false
|
||||||
|
for arg in "$@" ; do
|
||||||
|
if [ "$arg" = "--noconfig" ] ; then
|
||||||
|
no_config=true
|
||||||
|
elif [ "$arg" = "--usejikes" ] ; then
|
||||||
|
use_jikes_default=true
|
||||||
|
elif [ "$arg" = "--execdebug" ] ; then
|
||||||
|
ant_exec_debug=true
|
||||||
|
elif [ my"$arg" = my"--h" -o my"$arg" = my"--help" ] ; then
|
||||||
|
show_help=true
|
||||||
|
ant_exec_args="$ant_exec_args -h"
|
||||||
|
else
|
||||||
|
if [ my"$arg" = my"-h" -o my"$arg" = my"-help" ] ; then
|
||||||
|
show_help=true
|
||||||
|
fi
|
||||||
|
ant_exec_args="$ant_exec_args \"$arg\""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Source/default ant configuration
|
||||||
|
if $no_config ; then
|
||||||
|
rpm_mode=false
|
||||||
|
usejikes=$use_jikes_default
|
||||||
|
else
|
||||||
|
# load system-wide ant configuration
|
||||||
|
if [ -f "/etc/ant.conf" ] ; then
|
||||||
|
. /etc/ant.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
# load user ant configuration
|
||||||
|
if [ -f "$HOME/.ant/ant.conf" ] ; then
|
||||||
|
. $HOME/.ant/ant.conf
|
||||||
|
fi
|
||||||
|
if [ -f "$HOME/.antrc" ] ; then
|
||||||
|
. "$HOME/.antrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# provide default configuration values
|
||||||
|
if [ -z "$rpm_mode" ] ; then
|
||||||
|
rpm_mode=false
|
||||||
|
fi
|
||||||
|
if [ -z "$usejikes" ] ; then
|
||||||
|
usejikes=$use_jikes_default
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Setup Java environment in rpm mode
|
||||||
|
if $rpm_mode ; then
|
||||||
|
if [ -f /usr/share/java-utils/java-functions ] ; then
|
||||||
|
. /usr/share/java-utils/java-functions
|
||||||
|
set_jvm
|
||||||
|
set_javacmd
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OS specific support. $var _must_ be set to either true or false.
|
||||||
|
cygwin=false;
|
||||||
|
darwin=false;
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN*) cygwin=true ;;
|
||||||
|
Darwin*) darwin=true
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$ANT_HOME" -o ! -d "$ANT_HOME" ] ; then
|
||||||
|
# try to find ANT
|
||||||
|
if [ -d /opt/ant ] ; then
|
||||||
|
ANT_HOME=/opt/ant
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "${HOME}/opt/ant" ] ; then
|
||||||
|
ANT_HOME="${HOME}/opt/ant"
|
||||||
|
fi
|
||||||
|
|
||||||
|
## resolve links - $0 may be a link to ant's home
|
||||||
|
PRG="$0"
|
||||||
|
progname=`basename "$0"`
|
||||||
|
|
||||||
|
# need this for relative symlinks
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
ANT_HOME=`dirname "$PRG"`/..
|
||||||
|
|
||||||
|
# make it fully qualified
|
||||||
|
ANT_HOME=`cd "$ANT_HOME" && pwd`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$ANT_HOME" ] &&
|
||||||
|
ANT_HOME=`cygpath --unix "$ANT_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set ANT_LIB location
|
||||||
|
ANT_LIB="${ANT_HOME}/lib"
|
||||||
|
|
||||||
|
if [ -z "$JAVACMD" ] ; then
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD=`which java 2> /dev/null `
|
||||||
|
if [ -z "$JAVACMD" ] ; then
|
||||||
|
JAVACMD=java
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
echo "Error: JAVA_HOME is not defined correctly."
|
||||||
|
echo " We cannot execute $JAVACMD"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build local classpath using just the launcher in non-rpm mode or
|
||||||
|
# use the Jpackage helper in rpm mode with basic and default jars
|
||||||
|
# specified in the ant.conf configuration. Because the launcher is
|
||||||
|
# used, libraries linked in ANT_HOME will also be include, but this
|
||||||
|
# is discouraged as it is not java-version safe. A user should
|
||||||
|
# request optional jars and their dependencies via the OPT_JAR_LIST
|
||||||
|
# variable
|
||||||
|
if $rpm_mode && [ -f /usr/bin/build-classpath ] ; then
|
||||||
|
LOCALCLASSPATH="$(/usr/bin/build-classpath ant ant-launcher jaxp_parser_impl xml-commons-apis)"
|
||||||
|
# If the user requested to try to add some other jars to the classpath
|
||||||
|
if [ -n "$OPT_JAR_LIST" ] ; then
|
||||||
|
_OPTCLASSPATH="$(/usr/bin/build-classpath $OPT_JAR_LIST 2> /dev/null)"
|
||||||
|
if [ -n "$_OPTCLASSPATH" ] ; then
|
||||||
|
LOCALCLASSPATH="$LOCALCLASSPATH:$_OPTCLASSPATH"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Explicitly add javac path to classpath, assume JAVA_HOME set
|
||||||
|
# properly in rpm mode
|
||||||
|
if [ -f "$JAVA_HOME/lib/tools.jar" ] ; then
|
||||||
|
LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/tools.jar"
|
||||||
|
fi
|
||||||
|
if [ -f "$JAVA_HOME/lib/classes.zip" ] ; then
|
||||||
|
LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/classes.zip"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if CLASSPATH_OVERRIDE env var is set, LOCALCLASSPATH will be
|
||||||
|
# user CLASSPATH first and ant-found jars after.
|
||||||
|
# In that case, the user CLASSPATH will override ant-found jars
|
||||||
|
#
|
||||||
|
# if CLASSPATH_OVERRIDE is not set, we'll have the normal behaviour
|
||||||
|
# with ant-found jars first and user CLASSPATH after
|
||||||
|
if [ -n "$CLASSPATH" ] ; then
|
||||||
|
# merge local and specified classpath
|
||||||
|
if [ -z "$LOCALCLASSPATH" ] ; then
|
||||||
|
LOCALCLASSPATH="$CLASSPATH"
|
||||||
|
elif [ -n "$CLASSPATH_OVERRIDE" ] ; then
|
||||||
|
LOCALCLASSPATH="$CLASSPATH:$LOCALCLASSPATH"
|
||||||
|
else
|
||||||
|
LOCALCLASSPATH="$LOCALCLASSPATH:$CLASSPATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# remove class path from launcher -lib option
|
||||||
|
CLASSPATH=""
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# not using rpm_mode; use launcher to determine classpaths
|
||||||
|
if [ -z "$LOCALCLASSPATH" ] ; then
|
||||||
|
LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar
|
||||||
|
else
|
||||||
|
LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar:$LOCALCLASSPATH
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
# OSX hack to make Ant work with jikes
|
||||||
|
if $darwin ; then
|
||||||
|
OSXHACK="${JAVA_HOME}/../Classes"
|
||||||
|
if [ -d "${OSXHACK}" ] ; then
|
||||||
|
for i in "${OSXHACK}"/*.jar
|
||||||
|
do
|
||||||
|
JIKESPATH="$JIKESPATH:$i"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Allow Jikes support (off by default)
|
||||||
|
if $usejikes; then
|
||||||
|
ANT_OPTS="$ANT_OPTS -Dbuild.compiler=jikes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to appropriate format before running java
|
||||||
|
if $cygwin; then
|
||||||
|
if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then
|
||||||
|
format=mixed
|
||||||
|
else
|
||||||
|
format=windows
|
||||||
|
fi
|
||||||
|
ANT_HOME=`cygpath --$format "$ANT_HOME"`
|
||||||
|
ANT_LIB=`cygpath --$format "$ANT_LIB"`
|
||||||
|
JAVA_HOME=`cygpath --$format "$JAVA_HOME"`
|
||||||
|
LOCALCLASSPATH=`cygpath --path --$format "$LOCALCLASSPATH"`
|
||||||
|
if [ -n "$CLASSPATH" ] ; then
|
||||||
|
CLASSPATH=`cygpath --path --$format "$CLASSPATH"`
|
||||||
|
fi
|
||||||
|
CYGHOME=`cygpath --$format "$HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show script help if requested
|
||||||
|
if $show_help ; then
|
||||||
|
echo $0 '[script options] [options] [target [target2 [target3] ..]]'
|
||||||
|
echo 'Script Options:'
|
||||||
|
echo ' --help, --h print this message and ant help'
|
||||||
|
echo ' --noconfig suppress sourcing of /etc/ant.conf,'
|
||||||
|
echo ' $HOME/.ant/ant.conf, and $HOME/.antrc'
|
||||||
|
echo ' configuration files'
|
||||||
|
echo ' --usejikes enable use of jikes by default, unless'
|
||||||
|
echo ' set explicitly in configuration files'
|
||||||
|
echo ' --execdebug print ant exec line generated by this'
|
||||||
|
echo ' launch script'
|
||||||
|
echo ' '
|
||||||
|
fi
|
||||||
|
# add a second backslash to variables terminated by a backslash under cygwin
|
||||||
|
if $cygwin; then
|
||||||
|
case "$ANT_HOME" in
|
||||||
|
*\\ )
|
||||||
|
ANT_HOME="$ANT_HOME\\"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$CYGHOME" in
|
||||||
|
*\\ )
|
||||||
|
CYGHOME="$CYGHOME\\"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$JIKESPATH" in
|
||||||
|
*\\ )
|
||||||
|
JIKESPATH="$JIKESPATH\\"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$LOCALCLASSPATH" in
|
||||||
|
*\\ )
|
||||||
|
LOCALCLASSPATH="$LOCALCLASSPATH\\"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$CLASSPATH" in
|
||||||
|
*\\ )
|
||||||
|
CLASSPATH="$CLASSPATH\\"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
# Execute ant using eval/exec to preserve spaces in paths,
|
||||||
|
# java options, and ant args
|
||||||
|
ant_sys_opts=
|
||||||
|
if [ -n "$CYGHOME" ]; then
|
||||||
|
if [ -n "$JIKESPATH" ]; then
|
||||||
|
ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\" -Dcygwin.user.home=\"$CYGHOME\""
|
||||||
|
else
|
||||||
|
ant_sys_opts="-Dcygwin.user.home=\"$CYGHOME\""
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -n "$JIKESPATH" ]; then
|
||||||
|
ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
ant_exec_command="exec \"$JAVACMD\" $ANT_OPTS -classpath \"$LOCALCLASSPATH\" -Dant.home=\"$ANT_HOME\" -Dant.library.dir=\"$ANT_LIB\" $ant_sys_opts org.apache.tools.ant.launch.Launcher $ANT_ARGS -lib \"$CLASSPATH\" $ant_exec_args"
|
||||||
|
if $ant_exec_debug ; then
|
||||||
|
echo $ant_exec_command
|
||||||
|
fi
|
||||||
|
eval $ant_exec_command
|
297
jasmin/jasmin-2.4/build.xml
Normal file
297
jasmin/jasmin-2.4/build.xml
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
<!-- ===========================================================================
|
||||||
|
|
||||||
|
Installing the build tools
|
||||||
|
==========================
|
||||||
|
|
||||||
|
The Jasmin build system is based on Jakarta Ant, which is a Java building tool
|
||||||
|
originally developed for the Jakarta Tomcat project but now used in many other
|
||||||
|
Apache projects and extended by many developers.
|
||||||
|
|
||||||
|
Ant is a little but very handy tool that uses a build file written in XML
|
||||||
|
(this file) as building instructions. For more information refer to
|
||||||
|
"http://jakarta.apache.org/ant/".
|
||||||
|
|
||||||
|
Jasmin includes its own copy of the ant library in the lib directory.
|
||||||
|
|
||||||
|
The only other thing that you have to make sure of is that the
|
||||||
|
"JAVA_HOME" environment property is set to match the top level directory
|
||||||
|
containing the JVM you want to use. For example:
|
||||||
|
|
||||||
|
C:\> set JAVA_HOME=C:\jdk1.4
|
||||||
|
|
||||||
|
or on Unix:
|
||||||
|
|
||||||
|
% setenv JAVA_HOME /usr/local/java
|
||||||
|
(csh)
|
||||||
|
> JAVA_HOME=/usr/java; export JAVA_HOME
|
||||||
|
(ksh, bash)
|
||||||
|
|
||||||
|
That's it!
|
||||||
|
|
||||||
|
Building instructions
|
||||||
|
=====================
|
||||||
|
|
||||||
|
First, make sure your current working directory is
|
||||||
|
where this very file is located. Then type:
|
||||||
|
|
||||||
|
./build.sh all (unix)
|
||||||
|
build.bat all (win32)
|
||||||
|
|
||||||
|
To build the framework, examples, and tests or:
|
||||||
|
|
||||||
|
./build.sh (unix)
|
||||||
|
build.bat (win32)
|
||||||
|
|
||||||
|
To list all the possible build targets.
|
||||||
|
|
||||||
|
If everything is right (see *) and all the required packages are visible, this action
|
||||||
|
will generate a build directory ./build, containing the jar file:
|
||||||
|
|
||||||
|
jasmin.jar - This jar contains the Jasmin assembler
|
||||||
|
|
||||||
|
This jar file can be run by the command
|
||||||
|
|
||||||
|
java -jar jasmin.jar <filenames>
|
||||||
|
|
||||||
|
from within the ./build directory.
|
||||||
|
|
||||||
|
* On Win/98 you may get an "Out of Environment Space" error message. This happens if
|
||||||
|
Windows provides too small a space for environment variables. To work around this
|
||||||
|
limitation:
|
||||||
|
Close the DOS window (the error can corrupt its CLASSPATH variable).
|
||||||
|
Open a new DOS window. Click on the MS-DOS icon at the top left of the window.
|
||||||
|
Select the Properties option.
|
||||||
|
Click on the Memory tab.
|
||||||
|
Adjust the "Initial Environment" drop-down box from "Auto" to "2816".
|
||||||
|
Click OK.
|
||||||
|
Then try building.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project name="Jasmin" default="usage" basedir=".">
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Initialization target -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="init">
|
||||||
|
<tstamp/>
|
||||||
|
<property name="Name" value="Jasmin"/>
|
||||||
|
<property name="name" value="jasmin"/>
|
||||||
|
<property name="version" value="2.1"/>
|
||||||
|
<property name="year" value="2006"/>
|
||||||
|
|
||||||
|
<echo message="----------- ${Name} ${version} [${year}] ------------"/>
|
||||||
|
|
||||||
|
<property name="build.compiler" value="modern"/>
|
||||||
|
<property name="debug" value="on"/>
|
||||||
|
<property name="optimize" value="on"/>
|
||||||
|
<property name="deprecation" value="on"/>
|
||||||
|
<property name="packages" value="jasmin.*,jas.*,scm.*"/>
|
||||||
|
|
||||||
|
<!-- Define the source directories -->
|
||||||
|
<property name="root.dir" value="./"/>
|
||||||
|
<property name="docs.dir" value="${root.dir}/docs"/>
|
||||||
|
<property name="lib.dir" value="${root.dir}/lib"/>
|
||||||
|
<property name="src.dir" value="${root.dir}/src"/>
|
||||||
|
|
||||||
|
<!-- Define the source build directories -->
|
||||||
|
<property name="build.dir" value="${root.dir}/build"/>
|
||||||
|
<property name="build.lib" value="${build.dir}/lib"/>
|
||||||
|
<property name="build.jasmin.src" value="${build.dir}/jasmin/src"/>
|
||||||
|
<property name="build.jasmin.dest" value="${build.dir}/jasmin/classes"/>
|
||||||
|
<property name="apidocs.dir" value="${docs.dir}/api"/>
|
||||||
|
|
||||||
|
<!-- Define the distribution directories -->
|
||||||
|
<property name="dist.root" value="${root.dir}/dist"/>
|
||||||
|
<property name="sourcedist.dir" value="${dist.root}/${name}-${version}/${name}-${version}"/>
|
||||||
|
<property name="compiledist.dir" value="${dist.root}/${name}-${version}/${name}-${version}"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Help on usage -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="usage">
|
||||||
|
<echo message=""/>
|
||||||
|
<echo message=""/>
|
||||||
|
<echo message="Jasmin Build file"/>
|
||||||
|
<echo message="-------------------------------------------------------------"/>
|
||||||
|
<echo message=""/>
|
||||||
|
<echo message=" available targets are:"/>
|
||||||
|
<echo message=""/>
|
||||||
|
<echo message=" all --> builds all the jars in ./build"/>
|
||||||
|
<echo message=" parser --> regenerates parser.java from parser.cup "/>
|
||||||
|
<echo message=" docs --> builds the documentation in ./docs/api"/>
|
||||||
|
<echo message=" clean --> restores distribution to original state"/>
|
||||||
|
<echo message=" sourcedist --> builds and zips the source distribution"/>
|
||||||
|
<echo message=" usage --> (default) displays build menu"/>
|
||||||
|
<echo message=""/>
|
||||||
|
<echo message=" See the comments inside the build.xml file for more details."/>
|
||||||
|
<echo message="-------------------------------------------------------------"/>
|
||||||
|
<echo message=""/>
|
||||||
|
<echo message=""/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Prepares the build directory -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="prepare" depends="init">
|
||||||
|
<mkdir dir="${build.dir}"/>
|
||||||
|
<mkdir dir="${build.lib}"/>
|
||||||
|
|
||||||
|
<copy todir="${build.lib}">
|
||||||
|
<fileset dir="${lib.dir}"/>
|
||||||
|
</copy>
|
||||||
|
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Prepares the jasmin source code -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="prepare-jasmin" depends="prepare">
|
||||||
|
<mkdir dir="${build.jasmin.src}"/>
|
||||||
|
<mkdir dir="${build.jasmin.dest}"/>
|
||||||
|
|
||||||
|
<copy todir="${build.jasmin.src}">
|
||||||
|
<fileset dir="${src.dir}"/>
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Compiles the jasmin source code -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="compile-jasmin" depends="prepare-jasmin">
|
||||||
|
<javac srcdir="${build.jasmin.src}"
|
||||||
|
source="1.4"
|
||||||
|
destdir="${build.jasmin.dest}"
|
||||||
|
debug="${debug}"
|
||||||
|
deprecation="${deprecation}"
|
||||||
|
optimize="${optimize}"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Creates the jasmin.jar in ./build -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="jasmin" depends="compile-jasmin">
|
||||||
|
<jar jarfile="${root.dir}/${name}.jar"
|
||||||
|
basedir="${build.jasmin.dest}"
|
||||||
|
manifest="${build.jasmin.src}/jasmin.mf"
|
||||||
|
includes="jasmin/*.class,jas/*.class,java_cup/runtime/*.class"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Compiles the JavaCup library -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
|
||||||
|
<target name="compile-java_cup" depends="prepare-jasmin">
|
||||||
|
<mkdir dir="${build.jasmin.dest}/java_cup"/>
|
||||||
|
<javac srcdir="${build.jasmin.src}/java_cup"
|
||||||
|
source="1.4"
|
||||||
|
destdir="${build.jasmin.dest}/java_cup"
|
||||||
|
debug="${debug}"
|
||||||
|
deprecation="${deprecation}"
|
||||||
|
optimize="${optimize}"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="java_cup" depends="compile-java_cup">
|
||||||
|
<jar jarfile="${root.dir}/lib/java_cup.jar"
|
||||||
|
basedir="${build.jasmin.dest}"
|
||||||
|
includes="java_cup/*.class,java_cup/runtime/*.class"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This task runs Java Cup to generate the Jasmin Parser (parser.java)
|
||||||
|
from the CUP file (parser.cup) in the Jasmin src directory. You only need to
|
||||||
|
run this task if you edit parser.cup.
|
||||||
|
-->
|
||||||
|
<target name="parser" depends="java_cup">
|
||||||
|
<java classname="java_cup.Main" output="test.java" input="src/jasmin/parser.cup">
|
||||||
|
<classpath>
|
||||||
|
<pathelement location="${root.dir}/lib/java_cup.jar"/>
|
||||||
|
</classpath>
|
||||||
|
</java>
|
||||||
|
<move file="parser.java" tofile="src/jasmin/parser.java"/>
|
||||||
|
<move file="sym.java" tofile="src/jasmin/sym.java"/>
|
||||||
|
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Build all jars in ./build -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="all" depends="jasmin,docs"/>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Creates the API documentation in ./docs/api/ -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="docs">
|
||||||
|
<mkdir dir="${apidocs.dir}"/>
|
||||||
|
<javadoc packagenames="${packages}"
|
||||||
|
link="http://java.sun.com/j2se/1.4/docs/api"
|
||||||
|
sourcepath="${src.dir}"
|
||||||
|
destdir="${apidocs.dir}"
|
||||||
|
author="true"
|
||||||
|
additionalparam="-source 1.4"
|
||||||
|
version="true"
|
||||||
|
use="true"
|
||||||
|
splitindex="true"
|
||||||
|
noindex="false"
|
||||||
|
windowtitle="${Name} API"
|
||||||
|
doctitle="${Name}"
|
||||||
|
bottom="Copyright © ${year} Jonathan Meyer, USA All rights reserved."
|
||||||
|
/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Build source distribution in ./dist -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="sourcedist" depends="clean">
|
||||||
|
<mkdir dir="${dist.root}"/>
|
||||||
|
<mkdir dir="${sourcedist.dir}"/>
|
||||||
|
|
||||||
|
<copy todir="${sourcedist.dir}">
|
||||||
|
<fileset dir="${root.dir}"/>
|
||||||
|
</copy>
|
||||||
|
|
||||||
|
<!-- Now delete what we dont want, probably a better way to do this -->
|
||||||
|
<delete dir="${sourcedist.dir}/dist"/>
|
||||||
|
<delete dir="${sourcedist.dir}/classes"/>
|
||||||
|
|
||||||
|
<zip zipfile="${dist.root}/${name}-${version}.zip"
|
||||||
|
basedir="${dist.root}/${name}-${version}"
|
||||||
|
whenempty="create"
|
||||||
|
/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Build compiled distribution in ./dist -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="compiledist" depends="clean, all">
|
||||||
|
<mkdir dir="${dist.root}"/>
|
||||||
|
<mkdir dir="${compiledist.dir}"/>
|
||||||
|
|
||||||
|
<copy todir="${compiledist.dir}">
|
||||||
|
<fileset dir="${root.dir}"/>
|
||||||
|
</copy>
|
||||||
|
|
||||||
|
<!-- Now delete what we dont want, probably a better way to do this -->
|
||||||
|
<delete dir="${compiledist.dir}/dist"/>
|
||||||
|
<delete dir="${compiledist.dir}/build"/>
|
||||||
|
|
||||||
|
|
||||||
|
<zip zipfile="${dist.root}/${name}-${version}.zip"
|
||||||
|
basedir="${dist.root}/${name}-${version}"
|
||||||
|
whenempty="create"
|
||||||
|
/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<!-- Clean restores distribution to original state -->
|
||||||
|
<!-- =================================================================== -->
|
||||||
|
<target name="clean" depends="init">
|
||||||
|
<delete dir="${build.dir}"/>
|
||||||
|
<delete dir="${dist.root}"/>
|
||||||
|
<delete dir="${apidocs.dir}"/>
|
||||||
|
</target>
|
||||||
|
</project>
|
||||||
|
|
||||||
|
<!-- End of file -->
|
114
jasmin/jasmin-2.4/changes.txt
Normal file
114
jasmin/jasmin-2.4/changes.txt
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
Jasmin Revision History Jonathan Meyer
|
||||||
|
|
||||||
|
15 Oct 2004 - Release 1.1
|
||||||
|
|
||||||
|
* Switched to Ant Build System
|
||||||
|
|
||||||
|
* Moved java_cup and jas sources into src directory
|
||||||
|
|
||||||
|
* Updated documentation to use style sheets
|
||||||
|
|
||||||
|
* Changed docs to reflect using jar files rather than class files
|
||||||
|
|
||||||
|
* Uploaded to SourceForge
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
11 Apr 97 - Release 1.06.
|
||||||
|
|
||||||
|
11 Apr 97
|
||||||
|
|
||||||
|
* Fixed bug which prevented the source name from being written out
|
||||||
|
in the class file
|
||||||
|
|
||||||
|
* Improved README file
|
||||||
|
|
||||||
|
2 Mar 97 - Release 1.05.
|
||||||
|
|
||||||
|
1 Mar 97
|
||||||
|
|
||||||
|
* Moved scripts into a bin directory.
|
||||||
|
|
||||||
|
* Added support for Visual J++.
|
||||||
|
|
||||||
|
Added vjasmin.bat, for running Jasmin using Visual J++.
|
||||||
|
|
||||||
|
Converted JAS/Jasmin to use its own internal RuntimeConstants, so that
|
||||||
|
there is no longer any dependency on Sun's version (needed by J++).
|
||||||
|
|
||||||
|
* Tidied API:
|
||||||
|
|
||||||
|
Renamed "Jasmin" class "ClassFile" (sorry to those of you using the API
|
||||||
|
from 1.04). The ClassFile class is documented in the doc/api directory.
|
||||||
|
|
||||||
|
* Mods for Java 1.1:
|
||||||
|
|
||||||
|
Classes now set the ACC_SUPER bit in their access flags.
|
||||||
|
i2b/i2s/i2c are now synonyms for int2byte, int2short, int2char.
|
||||||
|
invokespecial is now a synonym for invokenonvirtual.
|
||||||
|
|
||||||
|
* Mods to pick up documentation in book:
|
||||||
|
|
||||||
|
"wide" is now a recognized instruction in Jasmin files - although the assembler
|
||||||
|
just ignores it!
|
||||||
|
|
||||||
|
Added the optional <high> parameter to tableswitch.
|
||||||
|
|
||||||
|
* Fixed bug in .catch all
|
||||||
|
|
||||||
|
10 Feb 96 - Release 1.04.
|
||||||
|
|
||||||
|
8 Feb 97
|
||||||
|
* Updated to use latest version of JAS. This fixes some bugs in the
|
||||||
|
earlier release (including handling of _w instructions)
|
||||||
|
|
||||||
|
* Split several of the internal classes into smaller pieces.
|
||||||
|
|
||||||
|
* Restructured internal sources so that Jasmin, Scanner and parser
|
||||||
|
no longer rely on static data structures. Now there is a public API
|
||||||
|
to Jasmin, for people that want to assemble classes using their own
|
||||||
|
data input/output streams.
|
||||||
|
|
||||||
|
30 Oct 96
|
||||||
|
|
||||||
|
* Added support for more \ escapes in quoted strings. In
|
||||||
|
particular, you can now use \nnn to specify a character using
|
||||||
|
octal.
|
||||||
|
|
||||||
|
2 Oct 96 - Release 1.03.
|
||||||
|
|
||||||
|
1 Oct 96
|
||||||
|
|
||||||
|
* Added better support for interfaces: added the .interface
|
||||||
|
directive (an alternative to the .class directive), and also a
|
||||||
|
.implements directive. Updates guide.html to mention these new
|
||||||
|
features.
|
||||||
|
|
||||||
|
24 Sept 96
|
||||||
|
|
||||||
|
* Fixed several problems with guide.html - thanks to feedback from
|
||||||
|
Shawn Silverman (umsilve1@cc.umanitoba.ca).
|
||||||
|
|
||||||
|
23 Aug 96
|
||||||
|
|
||||||
|
* Tidied up documentation and implementation for wide instructions.
|
||||||
|
|
||||||
|
Now ldc and ldc_w are used for single-word items, whereas
|
||||||
|
ldc2_w is used for two word items (previously, I had ldc_w as
|
||||||
|
a synonym for ldc2_w - oops).
|
||||||
|
|
||||||
|
25 July 96
|
||||||
|
|
||||||
|
* Added documentation for .var directive.
|
||||||
|
|
||||||
|
* Fixed line numbering produced by -g flag (I hope).
|
||||||
|
|
||||||
|
* Improved error reporting slightly.
|
||||||
|
|
||||||
|
24 July 96
|
||||||
|
|
||||||
|
* Added fix to scanner to handle Ctrl-M characters,
|
||||||
|
for DOS/NT Systems. (Thanks sbk!)
|
||||||
|
|
||||||
|
18 July 96 - Release 1.0.
|
182
jasmin/jasmin-2.4/docs/about.html
Normal file
182
jasmin/jasmin-2.4/docs/about.html
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>About Jasmin</title>
|
||||||
|
<link href="style.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr><td width=550>
|
||||||
|
<center>
|
||||||
|
<p><img src=jasmin_icon.jpg></p>
|
||||||
|
<p>
|
||||||
|
<div class="h1">ABOUT JASMIN</div>
|
||||||
|
Jonathan Meyer, July 1996
|
||||||
|
</p>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<h1>Introduction</h1>
|
||||||
|
|
||||||
|
This document tries to answer some questions you might have
|
||||||
|
about Jasmin. In particular, several people have asked me what
|
||||||
|
Jasmin is, why they might use Jasmin, and why I wrote it in the
|
||||||
|
first place. I've tried to give some answers to these questions
|
||||||
|
below.<p>
|
||||||
|
|
||||||
|
<h1>Jasmin Assembler</h1>
|
||||||
|
|
||||||
|
Jasmin is a Java Assembler Interface. It takes ASCII descriptions for Java
|
||||||
|
classes, written in a simple assembler-like syntax using the Java Virtual
|
||||||
|
Machine instructions set. It converts them into binary Java class files
|
||||||
|
suitable for loading into a Java interpreter.<p>
|
||||||
|
|
||||||
|
To give you a flavor, here is the Jasmin assembly code for HelloWorld:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.class public HelloWorld
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
;
|
||||||
|
; standard initializer (calls java.lang.Object's initializer)
|
||||||
|
;
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
;
|
||||||
|
; main() - prints out Hello World
|
||||||
|
;
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit stack 2 ; up to two items can be pushed
|
||||||
|
|
||||||
|
; push System.out onto the stack
|
||||||
|
getstatic java/lang/System/out Ljava/io/PrintStream;
|
||||||
|
|
||||||
|
; push a string onto the stack
|
||||||
|
ldc "Hello World!"
|
||||||
|
|
||||||
|
; call the PrintStream.println() method.
|
||||||
|
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
; done
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin was originally created as a companion to the book "Java Virtual Machine",
|
||||||
|
written by Jon Meyer and Troy Downing and published by O'Reilly Associates. The
|
||||||
|
book is now out of print. Jasmin survives as a SourceForge Open Source project.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>Motivation for Jasmin</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin was written because, at the time that we wrote the Java Virtual Machine
|
||||||
|
book for O'Reilly, Sun had not published an assembler format for the
|
||||||
|
Java virtual machine.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Generating a binary Java .class file is pretty fiddly. Its like
|
||||||
|
creating an a.out (or .exe) file by hand. Even using a Java package like
|
||||||
|
JAS (a Java API for creating class files, used internally by Jasmin and written by KB Sriram), you
|
||||||
|
need to know a lot about the philosophy of the Java Virtual
|
||||||
|
Machine before you can write something at the Virtual
|
||||||
|
Machine level and generate a Java class. <p>
|
||||||
|
|
||||||
|
We wanted something that made it very easy for a student or programmer
|
||||||
|
to explore the Java Virtual Machine, or write a new language
|
||||||
|
which targets the VM, without getting into the details of constant
|
||||||
|
pool indices, attribute tables, and so on.<p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Creating a Java assembler seemed like a good solution.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Unfortunately, Sun has not seen the need to define a standard Java
|
||||||
|
assembler format, and has not released tools perform Java assembly.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Sun does provide a javap program which can print the assembly code
|
||||||
|
in a class file. However, the javap output is inappropriate for
|
||||||
|
use as an assembler format. It is designed to be read by a person,
|
||||||
|
not to be parsed by an assembler, so it has a number of
|
||||||
|
omissions and drawbacks. </p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Internally, Sun has a Java assembler tool. In hindsight, the syntax used by their internal tool is nicer than
|
||||||
|
the Jasmin syntax. However, to my knowledge, their tool is still not widely available, nor is it a formally
|
||||||
|
supported part of the Sun JDK.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>Update on Jasmin Today (2004) </h1>
|
||||||
|
|
||||||
|
Since Jasmin was written, it has become the de-facto standard assembly format for Java. It is used in dozens of compiler classes throughout the world, and has
|
||||||
|
been ported and cloned multiple times. For better or worse, Jasmin remains the original Java assembler.
|
||||||
|
<p>
|
||||||
|
[As an interesting comparison, Microsoft .NET shipped out-of-box with an
|
||||||
|
assembler, a disassembler, a standard IL assembly format, and built-in libraries
|
||||||
|
for code-genning (generating classes on the fly). It would be great if Sun was
|
||||||
|
as comprehensive in their support of the JVM].
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>What can I do with Jasmin?</h1>
|
||||||
|
|
||||||
|
To give you some ideas, below are some theoretical Jasmin users/uses.<p>
|
||||||
|
|
||||||
|
<h3>Teachers</h3>
|
||||||
|
|
||||||
|
If you are teaching a compilers course, you could have students
|
||||||
|
write a compiler which generates Jasmin assembly files,
|
||||||
|
and then assembles those files into Java class files. Then you
|
||||||
|
can integrate the advantages of the Virtual Machine (portability,
|
||||||
|
the verifier, an object model...) into your courseware.<p>
|
||||||
|
|
||||||
|
<h3>Hobbyists</h3>
|
||||||
|
|
||||||
|
Jasmin lets you poke around in Java at the VM level, so that
|
||||||
|
you can gain a real understanding of how Java works and
|
||||||
|
what the Virtual Machine is like.<p>
|
||||||
|
|
||||||
|
<h3>System Implementors</h3>
|
||||||
|
|
||||||
|
If you are implementing a Java runtime system, Jasmin is
|
||||||
|
an essential tool for generating test classes.<p>
|
||||||
|
|
||||||
|
<h3>Advanced Programmers</h3>
|
||||||
|
|
||||||
|
You could use Jasmin to write a critical class or method by
|
||||||
|
hand (e.g. if you think that Java isn't doing things
|
||||||
|
as well as it could). <p>
|
||||||
|
|
||||||
|
Alternatively, you could create a syntax extension to the
|
||||||
|
Java language which uses Jasmin (or JAS). <p>
|
||||||
|
|
||||||
|
<h3>Language Implementors</h3>
|
||||||
|
|
||||||
|
If you want to create an implementation of your
|
||||||
|
favorite programming language which targets the
|
||||||
|
Virtual Machine, Jasmin may be a simpler approach than
|
||||||
|
writing a Java class file generator. This is especially
|
||||||
|
true if your compiler is implemented in something other
|
||||||
|
than Java, since you can create Java class files easily
|
||||||
|
without having to get involved in the details of the
|
||||||
|
binary file format.<p>
|
||||||
|
|
||||||
|
<h3>Security Wizards</h3>
|
||||||
|
|
||||||
|
Sun's claim that the Java class verifier protects you from
|
||||||
|
hostile programs is a pretty strong one. Jasmin lets you create
|
||||||
|
'hostile' class files and see if a Java implementation is really as
|
||||||
|
secure as it should be. <p>
|
||||||
|
|
||||||
|
<hr><address>Copyright (c) Jonathan Meyer, July 1996</address>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<a href="http://jasmin.sourceforge.net">Jasmin Home</a> |
|
||||||
|
<a href="http://www.cybergrain.com/">Jon Meyer's Home</a>
|
||||||
|
|
689
jasmin/jasmin-2.4/docs/guide.html
Normal file
689
jasmin/jasmin-2.4/docs/guide.html
Normal file
|
@ -0,0 +1,689 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Jasmin User Guide</title>
|
||||||
|
<link href="style.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr><td width=550>
|
||||||
|
<center>
|
||||||
|
<p><img src=jasmin_icon.jpg></p>
|
||||||
|
<p>
|
||||||
|
<div class="h1">JASMIN USER GUIDE</div>
|
||||||
|
Jonathan Meyer, July 1996
|
||||||
|
</p>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<h1>About This Document</h1>
|
||||||
|
|
||||||
|
This guide describes the rules and syntax used in Jasmin, and
|
||||||
|
how to run Jasmin. Note that this document doesn't
|
||||||
|
explain the Java Virtual Machine itself, or give syntax notes for
|
||||||
|
every instruction known to Jasmin. See the Java Virtual Machine specification
|
||||||
|
for more information on the JVM.<p>
|
||||||
|
|
||||||
|
<h1>What is Jasmin?</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin is an assembler for the Java Virtual Machine. It takes
|
||||||
|
ASCII descriptions of Java classes, written in a simple
|
||||||
|
assembler-like syntax using the Java Virtual
|
||||||
|
Machine instruction set. It converts them into binary Java class files,
|
||||||
|
suitable for loading by a Java runtime system.<p>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Jasmin was originally created as a companion to the book "Java Virtual Machine",
|
||||||
|
written by Jon Meyer and Troy Downing and published by O'Reilly Associates. The
|
||||||
|
book is now out of print. Jasmin survives as a SourceForge Open Source project.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>Jasmin Design</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin is designed as a simple assembler. It has a clean easy-to-learn
|
||||||
|
syntax with few bells and whistles. Where possible, Jasmin adopts a
|
||||||
|
one-to-one mapping between its syntax and the conventions followed by Java class files.
|
||||||
|
For example, package names in Jasmin are delimited with the '/' character
|
||||||
|
(e.g. "java/lang/String") used by the class file format, instead
|
||||||
|
of the '.' character (java.lang.String) used in the Java language.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The Jasmin assembler does little compile-time processing or
|
||||||
|
checking of the input code. For example, it doesn't check that
|
||||||
|
classes you reference actually exist, or that your type descriptors are
|
||||||
|
well formed. Jasmin also lacks many of the feautures
|
||||||
|
found in full macro assemblers. For example, it doesn't
|
||||||
|
inline mathematical expressions, perform variable
|
||||||
|
substitutions, or support macros.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
On the other hand, using Jasmin you can quickly try out nearly
|
||||||
|
all of the features of the Java Virtual Machine, including
|
||||||
|
methods, fields, subroutines, exception handlers, and so on.
|
||||||
|
The Jasmin syntax is also readable and compact.</p>
|
||||||
|
|
||||||
|
<h1>Running Jasmin</h1>
|
||||||
|
<p>
|
||||||
|
The <code>jasmin.jar</code> file is an executable JAR file that runs Jasmin.
|
||||||
|
For example:</p>
|
||||||
|
|
||||||
|
<pre><strong> java -jar jasmin.jar myfile.j</strong></pre>
|
||||||
|
|
||||||
|
<p>assembles the file "myfile.j". Jasmin looks at the
|
||||||
|
<code>.class</code> directive contained in the file to
|
||||||
|
decide where to place the output class file. So if myfile.j starts
|
||||||
|
with:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.class mypackage/MyClass
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>then Jasmin will place the output class file "MyClass.class" in the
|
||||||
|
subdirectory "mypackage" of the current directory. It will create the
|
||||||
|
mypackage directory if it doesn't exist.</p>
|
||||||
|
|
||||||
|
<p>You can use the "-d" option to tell jasmin to place the output
|
||||||
|
in an alternative directory. For example,</p>
|
||||||
|
|
||||||
|
<pre><strong> java -jar jasmin.jar -d /tmp myfile.j </strong></pre>
|
||||||
|
|
||||||
|
<p>will place the output in /tmp/mypackage/MyClass.class.</p>
|
||||||
|
|
||||||
|
<p>Finally, you can use the "-g" option to tell Jasmin to include
|
||||||
|
line number information (used by debuggers) in the resulting
|
||||||
|
.class file. Jasmin will number the lines in the Jasmin source
|
||||||
|
file that JVM instructions appear on. Then, if an error occurs,
|
||||||
|
you can see what instruction in the Jasmin source caused the error.
|
||||||
|
Note that specifying "-g" causes any .line directives within the
|
||||||
|
Jasmin file to be ignored.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>Statements</h1>
|
||||||
|
|
||||||
|
<p>Jasmin source files consists of a sequence of newline-separated statements.
|
||||||
|
There are three types of statement: </p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>directives
|
||||||
|
<li>instructions
|
||||||
|
<li>labels
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Directives and instructions can take <i>parameters</i>. These parameters
|
||||||
|
are placed on the same line as the directive or instruction,
|
||||||
|
separated by spaces.</p>
|
||||||
|
|
||||||
|
<h3>Directives</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Directive statements are used to give Jasmin meta-level information.
|
||||||
|
Directive statements consist of a directive name, and then zero or more
|
||||||
|
parameters separated by spaces, then a newline.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
All directive names start with a "." character. The directives in Jasmin are:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.catch .class .end .field .implements .interface .limit .line
|
||||||
|
.method .source .super .throws .var
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Some example directive statements are:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.limit stack 10
|
||||||
|
|
||||||
|
.method public myMethod()V
|
||||||
|
|
||||||
|
.class Foo
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The parameters used by each directive are described in more detail
|
||||||
|
later in the document.</p>
|
||||||
|
|
||||||
|
<h3>Instructions</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
An instruction statement consists of an instruction name, zero or
|
||||||
|
more parameters separated by spaces, and a newline.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin uses the standard mnemonics for JVM opcodes as instruction names.
|
||||||
|
For example, aload_1, bipush and iinc are all Jasmin instruction names.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Here are some examples of instruction statements:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
ldc "Hello World"
|
||||||
|
iinc 1 -1
|
||||||
|
bipush 10
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
</p>See <a href="instructions.html">Jasmin Instructions</a> for more details on
|
||||||
|
the syntax of instructions in Jasmin.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Labels</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
</p>A Jasmin label statement consists of a name followed by a ':', and a newline.
|
||||||
|
For example:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
Foo:
|
||||||
|
|
||||||
|
Label:
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>Label names cannot start with a numeric digit, and cannot contain
|
||||||
|
any of the special characters:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
= : . " -
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You cannot use directive names or instruction names as labels. Other
|
||||||
|
than that, there are few restrictions on label names.
|
||||||
|
For example, you could use the label:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
#_1:
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Labels can only be used within method definitions. The names are
|
||||||
|
local to that method.</p>
|
||||||
|
|
||||||
|
<h1>The Jasmin Tokenizer</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin tokenizes its input stream, splitting the stream into tokens
|
||||||
|
by looking for whitespace characters (spaces, tabs and newlines).
|
||||||
|
The tokenizer looks for:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>directive names
|
||||||
|
<li>instruction names
|
||||||
|
<li>labels
|
||||||
|
<li>comments
|
||||||
|
<li>type descriptor names
|
||||||
|
<li>class names
|
||||||
|
<li>numbers and quoted strings
|
||||||
|
<li>etc.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The rules used by the tokenizer are described below:</p>
|
||||||
|
|
||||||
|
<h3>Comments</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A comment is a token that starts with a ';' character, and
|
||||||
|
terminates with the newline character at the end of the line. </p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note that the semicolon must be preceded by a whitespace character (a space, tab, newline), i.e.
|
||||||
|
embedded semicolons are ignored. For example,</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
abc;def
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
is treated as a single token "abc;def", and</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
Ljava/lang/String;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
is the token "Ljava/lang/String;", whereas</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
foo ; baz ding
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
is the token "foo" followed by a comment "baz ding".</p>
|
||||||
|
|
||||||
|
<h3>Numbers and Strings</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In Jasmin, only simple decimal and integer numeric formats are
|
||||||
|
recognized. Floats in scientific or exponent format are not yet
|
||||||
|
supported. Character codes and octal aren't currently supported either. This
|
||||||
|
means you can have:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
1, 123, .25, 0.03, 0xA
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
but not</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
1e-10, 'a', '\u123'
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Quoted strings are also very basic. The full range of
|
||||||
|
backslash escape sequences are not supported yet, although "\n" and "\t"
|
||||||
|
are.</p>
|
||||||
|
|
||||||
|
<h3>Class Names</h3>
|
||||||
|
|
||||||
|
<p></p>Class names in Jasmin should be written using the Java class file format
|
||||||
|
conventions, so java.lang.String becomes java/lang/String.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Type Descriptors</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Type information is also written as they appear in class files (e.g.
|
||||||
|
the descriptor I speficies an integer, [Ljava/lang/Thread; is an
|
||||||
|
array of Threads, etc.).</p>
|
||||||
|
|
||||||
|
<h3>Methods</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Method names are specified using a single token, e.g.</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
is the method called "println" in the class java.io.PrintStream, which
|
||||||
|
has the type descriptor "(Ljava/lang/String;)V" (i.e. it takes a String
|
||||||
|
and returns no result). In general, a method specification
|
||||||
|
is formed of three parts: the characters before the last '/' form the class
|
||||||
|
name. The characters between the last '/' and '(' are the method name. The
|
||||||
|
rest of the string is the type descriptor for the method.</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
foo/baz/Myclass/myMethod(Ljava/lang/String;)V
|
||||||
|
--------------- ---------------------
|
||||||
|
| -------- |
|
||||||
|
| | |
|
||||||
|
class method descriptor
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
As another example, you would call the Java method: </p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
class mypackage.MyClass {
|
||||||
|
int foo(Object a, int b[]) { ... }
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
using:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
invokevirtual mypackage/MyClass/foo(Ljava/lang/Object;[I)I
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3>Fields</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Field names are specified in Jasmin using two tokens, one giving the name
|
||||||
|
and class of the field, the other giving its descriptor. For example:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
getstatic mypackage/MyClass/my_font Ljava/lang/Font;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
gets the value of the field called "my_font" in the class mypackage.MyClass.
|
||||||
|
The type of the field is "Ljava/lang/Font;" (i.e. a Font object).</p>
|
||||||
|
|
||||||
|
<h1>FILES</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin files start by giving information on the class
|
||||||
|
being defined in the file - such as the name of the
|
||||||
|
class, the name of the source file that the class originated from,
|
||||||
|
the name of the superclass, etc.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Typically, a Jasmin file starts with the three directives:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.source <source-file>
|
||||||
|
.class <access-spec> <class-name>
|
||||||
|
.super <class-name>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For example, the file defining MyClass might start with the directives:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.source MyClass.j
|
||||||
|
.class public MyClass
|
||||||
|
.super java/lang/Object
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3>.source directive</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The .source directive is optional. It specifies the
|
||||||
|
value of the "SourceFile" attribute for the class
|
||||||
|
file. (This is used by Java to print out debugging info
|
||||||
|
if something goes wrong in one of the methods in the class).
|
||||||
|
If you generated the Jasmin file automatically (e.g. as the result of
|
||||||
|
compiling a file written in another syntax) you should use the .source
|
||||||
|
directive to tell Java the name of the originating file. Note that
|
||||||
|
the source file name should not include any pathname. Use "foo.src"
|
||||||
|
but not "/home/user/foo.src".</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If no .source directive is given, the name of the Jasmin
|
||||||
|
file you are compiling is used instead as the SourceFile attribute
|
||||||
|
instead.</p>
|
||||||
|
|
||||||
|
<h3>.class and .super directives</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The .class and .super directive tell the JVM the name of this
|
||||||
|
class and its superclass. These directives take parameters as
|
||||||
|
follows:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><class-name></dt>
|
||||||
|
<dd>is the full name of the class, including
|
||||||
|
any package names. For example foo/baz/MyClass.<p>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dt><access-spec></dt>
|
||||||
|
<dd>defines access permissions and other attributes for
|
||||||
|
the class. This is a list of zero or more of the following
|
||||||
|
keywords:<p>
|
||||||
|
<dl><dd>
|
||||||
|
public, final, super, interface, abstract
|
||||||
|
</dl>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<h3>.interface directive</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note that, instead of using the directive .class,
|
||||||
|
you can alternatively use the directive .interface. This has
|
||||||
|
the same syntax as the .class directive, but indicates that the Jasmin file
|
||||||
|
is defining a Java interface. e.g.</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.interface public foo
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3>.implements directive</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
After .source, .class and .super, you can list the
|
||||||
|
interfaces that are implemented by the class you are defining, using
|
||||||
|
the .implements directive. The syntax of .implements is:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.implements <class-name>
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
where <class-name> has the same format as was used by .class and .super.
|
||||||
|
For example:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.class foo
|
||||||
|
.super java/lang/Object
|
||||||
|
.implements Edible
|
||||||
|
.implements java/lang/Throwable
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>Field Definitions</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
After the header information, the next section of the Jasmin file
|
||||||
|
is a list of field definitions.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A field is defined using the .field directive:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.field <access-spec> <field-name> <descriptor> [ = <value> ]
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
where:</p>
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><access-spec>
|
||||||
|
<dd>is one of the keywords:
|
||||||
|
<dl><dd>
|
||||||
|
public, private, protected, static, final,
|
||||||
|
volatile, transient
|
||||||
|
</dl>
|
||||||
|
</dl><p>
|
||||||
|
|
||||||
|
<dt><field-name>
|
||||||
|
<dd>is the name of the field.<p>
|
||||||
|
|
||||||
|
<dt><descriptor>
|
||||||
|
<dd>is its type descriptor.<p>
|
||||||
|
|
||||||
|
<dt><value>
|
||||||
|
<dd>is an integer, a quoted string or a decimal number, giving the
|
||||||
|
initial value of the field (for final fields).<p>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For example, the Java field definition:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
public int foo;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
becomes</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.field public foo I
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
whereas the constant:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
public static final float PI = 3.14;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
becomes</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.field public static final PI F = 3.14
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>Method Definitions</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
After listing the fields of the class, the rest of the Jasmin file lists
|
||||||
|
methods defined by the class.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A method is defined using the basic form:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.method <access-spec> <method-spec>
|
||||||
|
<statements>
|
||||||
|
.end method
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
where:</p>
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><access-spec>
|
||||||
|
<dd>is one of the keywords: public, private, protected, static, final,
|
||||||
|
synchronized, native, abstract<p>
|
||||||
|
|
||||||
|
<dt><method-spec>
|
||||||
|
<dd>is the name and type descriptor of the method.<p>
|
||||||
|
|
||||||
|
<dt><statements>
|
||||||
|
<dd>is the code defining the body of the method.<p>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Method definitions cannot be nested. Also, Jasmin does not
|
||||||
|
insert an implicit 'return' instruction at the end of a method. It is
|
||||||
|
up to you to ensure that your methods return cleanly. So
|
||||||
|
the most basic Jasmin method is something like:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.method foo()V
|
||||||
|
return ; must give a return statement
|
||||||
|
.end method
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3>Method Directives</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The following directives can be used only within method definitions:</p>
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><pre>.limit stack <integer></pre><p>
|
||||||
|
<dd>Sets the maximum size of the operand stack
|
||||||
|
required by the method.
|
||||||
|
|
||||||
|
<dt><pre>.limit locals <integer></pre><p>
|
||||||
|
<dd>Sets the number of local variables
|
||||||
|
required by the method.
|
||||||
|
|
||||||
|
<dt><pre>.line <integer></pre><p>
|
||||||
|
<dd>This is used to tag the subsequent
|
||||||
|
instruction(s) with a line number. Debuggers use this information,
|
||||||
|
together with the name of the source file (see .source above)
|
||||||
|
to show at what line in a method things went wrong. If you are
|
||||||
|
generating Jasmin files by compiling a source file,
|
||||||
|
this directive lets you indicate what line
|
||||||
|
numbers in the source file produced corrosponding Jasmin
|
||||||
|
instructions. For example:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.method foo()V
|
||||||
|
.line 5
|
||||||
|
bipush 10 // these instructions generated from line 5
|
||||||
|
istore_2 // of the source file.
|
||||||
|
.line 6
|
||||||
|
...
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<dt><pre>.var <var-number> is <name> <descriptor> from <label1> to <label2></pre><p>
|
||||||
|
<dd>The .var directive is used to define the name, type descriptor and scope of
|
||||||
|
a local variable number. This information is used by debuggers
|
||||||
|
so that they can be more helpful when printing out the values of local
|
||||||
|
variables (rather than printing just a local variable number, the
|
||||||
|
debugger can actually print out the name of the variable). For example:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.method foo()V
|
||||||
|
.limit locals 1
|
||||||
|
|
||||||
|
; declare variable 0 as an "int Count;"
|
||||||
|
; whose scope is the code between Label1 and Label2
|
||||||
|
;
|
||||||
|
.var 0 is Count I from Label1 to Label2
|
||||||
|
|
||||||
|
Label1:
|
||||||
|
bipush 10
|
||||||
|
istore_0
|
||||||
|
Label2:
|
||||||
|
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<dt><pre>.throws <classname></pre><p>
|
||||||
|
<dd>Indicates that this method can throw
|
||||||
|
exceptions of the type indicated by <classname>.
|
||||||
|
e.g.
|
||||||
|
<pre>
|
||||||
|
.throws java/io/IOException
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
This information isn't required by Java runtime systems,
|
||||||
|
but it is used by the Java compiler to check that methods
|
||||||
|
either catch exceptions they can cause, or declare
|
||||||
|
that they throw them.
|
||||||
|
|
||||||
|
<dt><pre>.catch <classname> from <label1> to <label2> using <label3></pre><p>
|
||||||
|
<dd>Appends an entry to the end of the exceptions table for the
|
||||||
|
method. The entry indicates that when an exception which is
|
||||||
|
an instance of <classname> or one of its subclasses is thrown
|
||||||
|
while executing the code between <label1> and <label2>, then
|
||||||
|
the runtime system should jump to <label3>. e.g.<p>
|
||||||
|
<pre>
|
||||||
|
.catch java/io/IOException from L1 to L2 using IO_Handler
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
If classname is the keyword "all", then exceptions of any
|
||||||
|
class are caught by the handler.<p>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<h3>Abstract Methods</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To declare an abstract method, write a method with no body. e.g.</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.method abstract myAbstract()V
|
||||||
|
.end method
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
note that abstract methods can have .throws directives, e.g.</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.method abstract anotherAbstract()V
|
||||||
|
.throws java/io/IOException
|
||||||
|
.end method
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>Instructions</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
JVM instructions are placed between the <code>.method</code> and
|
||||||
|
<code>.end method</code> directives. VM instructions can take zero or more
|
||||||
|
parameters, depending on the type of instruction used. Some example
|
||||||
|
instructions are shown below:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
iinc 1 -3 ; decrement local variable 1 by 3
|
||||||
|
|
||||||
|
bipush 10 ; push the integer 10 onto the stack
|
||||||
|
|
||||||
|
pop ; remove the top item from the stack.
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
See <a href="instructions.html">Jasmin Instructions</a> for more details on the syntax
|
||||||
|
of instructions in Jasmin.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr><address>Copyright (c) Jonathan Meyer, July 1996</address>
|
||||||
|
<hr>
|
||||||
|
<a href="http://jasmin.sourceforge.net">Jasmin Home</a> |
|
||||||
|
<a href="http://www.cybergrain.com">Jon Meyer's Home</a>
|
||||||
|
|
||||||
|
</td></tr></table>
|
||||||
|
</body>
|
||||||
|
</html>
|
65
jasmin/jasmin-2.4/docs/index.html
Normal file
65
jasmin/jasmin-2.4/docs/index.html
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Jasmin Home Page</title>
|
||||||
|
<link href="style.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr><td width=550>
|
||||||
|
<center>
|
||||||
|
<p><img src=jasmin_icon.jpg></p>
|
||||||
|
<p>
|
||||||
|
<div class="h1">JASMIN HOME PAGE</div>
|
||||||
|
Jonathan Meyer, Oct 2004
|
||||||
|
</p>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<h1>Introduction</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin is an assembler for the Java Virtual Machine. It takes
|
||||||
|
ASCII descriptions of Java classes, written in a simple
|
||||||
|
assembler-like syntax using the Java Virtual
|
||||||
|
Machine instruction set. It converts them into binary Java class files,
|
||||||
|
suitable for loading by a Java runtime system.<p>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin was originally created as a companion to the book "Java Virtual Machine",
|
||||||
|
written by Jon Meyer and Troy Downing and published by O'Reilly Associates.
|
||||||
|
Since then, it has become the de-facto standard assembly format for Java. It is used in dozens of compiler classes throughout the world, and has
|
||||||
|
been ported and cloned multiple times. For better or worse, Jasmin remains the oldest and the original Java assembler.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The O'Reilly JVM book is now out of print. Jasmin continues to survive as a SourceForge Open Source project.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>Documentation</h1>
|
||||||
|
<dl>
|
||||||
|
<dt>
|
||||||
|
<a href = "http://jasmin.sourceforge.net">Jasmin Home Page</a>
|
||||||
|
<dd>this file (on SourceForge.net).<p>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a href = "guide.html">Jasmin User Guide</a>
|
||||||
|
<dd>a brief user guide for using Jasmin.<p>
|
||||||
|
|
||||||
|
<dt><a href = "instructions.html">Jasmin Instructions</a>
|
||||||
|
<dd>the syntax of JVM instructions in Jasmin.<p>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a href = "about.html">About Jasmin</a>
|
||||||
|
<dd>describes the background to Jasmin, who might find it interesting, etc.
|
||||||
|
Includes an example piece of Jasmin assembler to look at.<p>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
|
||||||
|
<hr><address>Copyright (c) Jonathan Meyer, 2004</address>
|
||||||
|
<hr>
|
||||||
|
<a href="http://jasmin.sourceforge.net">Jasmin Home</a> |
|
||||||
|
<a href="http://www.cybergrain.com">Jon Meyer's Home</a>
|
||||||
|
|
||||||
|
</td></tr></table>
|
||||||
|
</body>
|
||||||
|
</html>
|
505
jasmin/jasmin-2.4/docs/instructions.html
Normal file
505
jasmin/jasmin-2.4/docs/instructions.html
Normal file
|
@ -0,0 +1,505 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Jasmin Instructions</title>
|
||||||
|
<link href="style.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table ID="Table1">
|
||||||
|
<tr><td width=550>
|
||||||
|
<center>
|
||||||
|
<p><img src=jasmin_icon.jpg></p>
|
||||||
|
<p>
|
||||||
|
<div class="h1">JASMIN INSTRUCTIONS</div>
|
||||||
|
Jonathan Meyer, July 1996
|
||||||
|
</p>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<h1>Introduction</h1>
|
||||||
|
|
||||||
|
This document shows the syntax and the types of parameters required by
|
||||||
|
each Java VM instruction in Jasmin. It also shows brief illustrative
|
||||||
|
examples.<p>
|
||||||
|
|
||||||
|
See <a href="guide.html">The Jasmin User Guide</a> for a description
|
||||||
|
of other aspects of the Jasmin syntax.<p>
|
||||||
|
|
||||||
|
<h1>Local variable instructions</h1>
|
||||||
|
|
||||||
|
The following instructions use local variables:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
ret <var-num>
|
||||||
|
aload <var-num>
|
||||||
|
astore <var-num>
|
||||||
|
dload <var-num>
|
||||||
|
dstore <var-num>
|
||||||
|
fload <var-num>
|
||||||
|
fstore <var-num>
|
||||||
|
iload <var-num>
|
||||||
|
istore <var-num>
|
||||||
|
lload <var-num>
|
||||||
|
lstore <var-num>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
for example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
aload 1 ; push local variable 1 onto the stack
|
||||||
|
ret 2 ; return to the address held in local variable 2
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>The bipush, sipush and iinc instructions</h1>
|
||||||
|
|
||||||
|
The bipush and sipush instructions take an integer as a
|
||||||
|
parameter:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
bipush <int>
|
||||||
|
sipush <int>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
for example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
bipush 100 ; push 100 onto the stack
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The iinc instruction takes two integer parameters:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
iinc <var-num> <amount>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
for example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
iinc 3 -10 ; subtract 10 from local variable 3
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>Branch instructions</h1>
|
||||||
|
|
||||||
|
The following instructions take a label as a parameter:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
goto <label>
|
||||||
|
goto_w <label>
|
||||||
|
if_acmpeq <label>
|
||||||
|
if_acmpne <label>
|
||||||
|
if_icmpeq <label>
|
||||||
|
if_icmpge <label>
|
||||||
|
if_icmpgt <label>
|
||||||
|
if_icmple <label>
|
||||||
|
if_icmplt <label>
|
||||||
|
if_icmpne <label>
|
||||||
|
ifeq <label>
|
||||||
|
ifge <label>
|
||||||
|
ifgt <label>
|
||||||
|
ifle <label>
|
||||||
|
iflt <label>
|
||||||
|
ifne <label>
|
||||||
|
ifnonnull <label>
|
||||||
|
ifnull <label>
|
||||||
|
jsr <label>
|
||||||
|
jsr_w <label>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
For example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
Label1:
|
||||||
|
goto Label1 ; jump to the code at Label1
|
||||||
|
; (an infinite loop!)
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>Class and object operations</h1>
|
||||||
|
|
||||||
|
The following instructions take a class name
|
||||||
|
as a parameter:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
anewarray <class>
|
||||||
|
checkcast <class>
|
||||||
|
instanceof <class>
|
||||||
|
new <class>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
For example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
new java/lang/String ; create a new String object
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>Method invokation</h1>
|
||||||
|
|
||||||
|
The following instructions are used to invoke methods:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
invokenonvirtual <method-spec>
|
||||||
|
invokestatic <method-spec>
|
||||||
|
invokevirtual <method-spec>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
for example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
; invokes java.io.PrintStream.println(String);
|
||||||
|
|
||||||
|
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
A method specification is formed of three parts: the characters before the
|
||||||
|
last '/' form the class name. The characters between the last '/' and '(' are
|
||||||
|
the method name. The rest of the string is the descriptor.<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
foo/baz/Myclass/myMethod(Ljava/lang/String;)V
|
||||||
|
--------------- ---------------------
|
||||||
|
| -------- |
|
||||||
|
| | |
|
||||||
|
class method descriptor
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
A special case is invokeinterface, which takes a <method-spec> and
|
||||||
|
an integer indicating how many arguments the method takes:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
invokeinterface <method-spec> <num-args>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
for example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
invokeinterface foo/Baz/myMethod(I)V 1
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>Field manipulation instructions</h1>
|
||||||
|
|
||||||
|
The four instructions getfield, getstatic, putfield and
|
||||||
|
putstatic have the form:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
getfield <field-spec> <descriptor>
|
||||||
|
getstatic <field-spec> <descriptor>
|
||||||
|
putfield <field-spec> <descriptor>
|
||||||
|
putstatic <field-spec> <descriptor>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
; get java.lang.System.out, which is a PrintStream
|
||||||
|
getstatic java/lang/System/out Ljava/io/PrintStream;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<field-spec> is composed of two parts, a classname and a fieldname. The
|
||||||
|
classname is all of the characters in the <field-spec> up to the last
|
||||||
|
'/' character, and the fieldname is the rest of the characters after the last
|
||||||
|
'/'. For example: <p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
foo/baz/AnotherClass/anotherFunField
|
||||||
|
-- class name ------ --field name --
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<descriptor> is the Java type descriptor of the field.
|
||||||
|
For example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
Ljava/io/PrintStream;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>The newarray instruction</h1>
|
||||||
|
|
||||||
|
The newarray instruction is followed by the type of the array,<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
newarray <array-type>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
for example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
newarray int
|
||||||
|
newarray short
|
||||||
|
newarray float
|
||||||
|
etc.
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>The multianewarray instruction</h1>
|
||||||
|
|
||||||
|
The multianewarray instruction takes two parameters,
|
||||||
|
the type descriptor for the array and the number of
|
||||||
|
dimensions to allocate:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
multianewarray <array-descriptor> <num-dimensions>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
for example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
multianewarray [[[I 2
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>The ldc and ldc_w instructions</h1>
|
||||||
|
|
||||||
|
The ldc and ldc_w instructions are followed by a constant:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
ldc <constant>
|
||||||
|
ldc_w <constant>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<constant> is either an integer, a floating point number, or a
|
||||||
|
quoted string. For example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
ldc 1.2 ; push a float
|
||||||
|
ldc 10 ; push an int
|
||||||
|
ldc "Hello World" ; push a String
|
||||||
|
ldc_w 3.141592654 ; push PI as a double
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>The lookupswitch instruction</h1>
|
||||||
|
|
||||||
|
The lookupswitch instruction has the syntax:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<lookupswitch> ::=
|
||||||
|
lookupswitch
|
||||||
|
<int1> : <label1>
|
||||||
|
<int2> : <label2>
|
||||||
|
...
|
||||||
|
default : <default-label>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
For example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
; If the int on the stack is 3, jump to Label1.
|
||||||
|
; If it is 5, jump to Label2.
|
||||||
|
; Otherwise jump to DefaultLabel.
|
||||||
|
|
||||||
|
lookupswitch
|
||||||
|
3 : Label1
|
||||||
|
5 : Label2
|
||||||
|
default : DefaultLabel
|
||||||
|
|
||||||
|
Label1:
|
||||||
|
... got 3
|
||||||
|
|
||||||
|
Label2:
|
||||||
|
... got 5
|
||||||
|
|
||||||
|
DefaultLabel:
|
||||||
|
... got something else
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>The tableswitch instruction</h1>
|
||||||
|
|
||||||
|
The tableswitch instruction has the syntax:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<tableswitch> ::=
|
||||||
|
tableswitch <low>
|
||||||
|
<label1>
|
||||||
|
<label2>
|
||||||
|
...
|
||||||
|
default : <default-label>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
For example:<p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
; If the int on the stack is 0, jump to Label1.
|
||||||
|
; If it is 1, jump to Label2.
|
||||||
|
; Otherwise jump to DefaultLabel.
|
||||||
|
|
||||||
|
tableswitch 0
|
||||||
|
Label1
|
||||||
|
Label2
|
||||||
|
default : DefaultLabel
|
||||||
|
|
||||||
|
Label1:
|
||||||
|
... got 0
|
||||||
|
|
||||||
|
Label2:
|
||||||
|
... got 1
|
||||||
|
|
||||||
|
DefaultLabel:
|
||||||
|
... got something else
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>No parameter</h1>
|
||||||
|
|
||||||
|
The following instructions (the majority) take no parameters:<p>
|
||||||
|
|
||||||
|
<dl><dd>
|
||||||
|
aaload
|
||||||
|
aastore
|
||||||
|
aconst_null
|
||||||
|
aload_0
|
||||||
|
aload_1
|
||||||
|
aload_2
|
||||||
|
aload_3
|
||||||
|
areturn
|
||||||
|
arraylength
|
||||||
|
astore_0
|
||||||
|
astore_1
|
||||||
|
astore_2
|
||||||
|
astore_3
|
||||||
|
athrow
|
||||||
|
baload
|
||||||
|
bastore
|
||||||
|
breakpoint
|
||||||
|
caload
|
||||||
|
castore
|
||||||
|
d2f
|
||||||
|
d2i
|
||||||
|
d2l
|
||||||
|
dadd
|
||||||
|
daload
|
||||||
|
dastore
|
||||||
|
dcmpg
|
||||||
|
dcmpl
|
||||||
|
dconst_0
|
||||||
|
dconst_1
|
||||||
|
ddiv
|
||||||
|
dload_0
|
||||||
|
dload_1
|
||||||
|
dload_2
|
||||||
|
dload_3
|
||||||
|
dmul
|
||||||
|
dneg
|
||||||
|
drem
|
||||||
|
dreturn
|
||||||
|
dstore_0
|
||||||
|
dstore_1
|
||||||
|
dstore_2
|
||||||
|
dstore_3
|
||||||
|
dsub
|
||||||
|
dup
|
||||||
|
dup2
|
||||||
|
dup2_x1
|
||||||
|
dup2_x2
|
||||||
|
dup_x1
|
||||||
|
dup_x2
|
||||||
|
f2d
|
||||||
|
f2i
|
||||||
|
f2l
|
||||||
|
fadd
|
||||||
|
faload
|
||||||
|
fastore
|
||||||
|
fcmpg
|
||||||
|
fcmpl
|
||||||
|
fconst_0
|
||||||
|
fconst_1
|
||||||
|
fconst_2
|
||||||
|
fdiv
|
||||||
|
fload_0
|
||||||
|
fload_1
|
||||||
|
fload_2
|
||||||
|
fload_3
|
||||||
|
fmul
|
||||||
|
fneg
|
||||||
|
frem
|
||||||
|
freturn
|
||||||
|
fstore_0
|
||||||
|
fstore_1
|
||||||
|
fstore_2
|
||||||
|
fstore_3
|
||||||
|
fsub
|
||||||
|
i2d
|
||||||
|
i2f
|
||||||
|
i2l
|
||||||
|
iadd
|
||||||
|
iaload
|
||||||
|
iand
|
||||||
|
iastore
|
||||||
|
iconst_0
|
||||||
|
iconst_1
|
||||||
|
iconst_2
|
||||||
|
iconst_3
|
||||||
|
iconst_4
|
||||||
|
iconst_5
|
||||||
|
iconst_m1
|
||||||
|
idiv
|
||||||
|
iload_0
|
||||||
|
iload_1
|
||||||
|
iload_2
|
||||||
|
iload_3
|
||||||
|
imul
|
||||||
|
ineg
|
||||||
|
int2byte
|
||||||
|
int2char
|
||||||
|
int2short
|
||||||
|
ior
|
||||||
|
irem
|
||||||
|
ireturn
|
||||||
|
ishl
|
||||||
|
ishr
|
||||||
|
istore_0
|
||||||
|
istore_1
|
||||||
|
istore_2
|
||||||
|
istore_3
|
||||||
|
isub
|
||||||
|
iushr
|
||||||
|
ixor
|
||||||
|
l2d
|
||||||
|
l2f
|
||||||
|
l2i
|
||||||
|
ladd
|
||||||
|
laload
|
||||||
|
land
|
||||||
|
lastore
|
||||||
|
lcmp
|
||||||
|
lconst_0
|
||||||
|
lconst_1
|
||||||
|
ldiv
|
||||||
|
lload_0
|
||||||
|
lload_1
|
||||||
|
lload_2
|
||||||
|
lload_3
|
||||||
|
lmul
|
||||||
|
lneg
|
||||||
|
lor
|
||||||
|
lrem
|
||||||
|
lreturn
|
||||||
|
lshl
|
||||||
|
lshr
|
||||||
|
lstore_0
|
||||||
|
lstore_1
|
||||||
|
lstore_2
|
||||||
|
lstore_3
|
||||||
|
lsub
|
||||||
|
lushr
|
||||||
|
lxor
|
||||||
|
monitorenter
|
||||||
|
monitorexit
|
||||||
|
nop
|
||||||
|
pop
|
||||||
|
pop2
|
||||||
|
return
|
||||||
|
saload
|
||||||
|
sastore
|
||||||
|
swap
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
pop ; remove the top item from the stack
|
||||||
|
iconst_1 ; push 1 onto the stack
|
||||||
|
swap ; swap the top two items on the stack
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<hr><address>Copyright (c) Jonathan Meyer, July 1996</address>
|
||||||
|
<hr>
|
||||||
|
<a href="http://mrl.nyu.edu/meyer/jvm/jasmin.html">Jasmin Home</a> |
|
||||||
|
<a href="http://mrl.nyu.edu/meyer/">Jon Meyer's Home</a>
|
BIN
jasmin/jasmin-2.4/docs/jasmin_icon.jpg
Normal file
BIN
jasmin/jasmin-2.4/docs/jasmin_icon.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
BIN
jasmin/jasmin-2.4/docs/javavm.gif
Normal file
BIN
jasmin/jasmin-2.4/docs/javavm.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
16
jasmin/jasmin-2.4/docs/style.css
Normal file
16
jasmin/jasmin-2.4/docs/style.css
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
td { font-family: Verdana,Arial,Helvetica,sans-serif; color: #000000; font-size: 12px; line-height: 16px; }
|
||||||
|
td h1 { font-family: Tahoma; padding: 1px; padding-left: 4px; color: white; background-color: #303030; font-size: 20px; line-height: 24px; font-weight: bold; }
|
||||||
|
td h2{ font-family: Tahoma; color: #000000; font-size: 14px; line-height: 16px; font-weight: bold; }
|
||||||
|
td h3 { font-family: Tahoma; color: #000000; font-size: 12px; line-height: 16px; font-weight: bold; }
|
||||||
|
|
||||||
|
.h1 { font-family: Times; color: #000000; font-size: 18px; line-height: 20px; font-weight: bold; }
|
||||||
|
|
||||||
|
/* main text hyperlinks */
|
||||||
|
a { color: #b11; TEXT-DECORATION: underline; }
|
||||||
|
a:visited {color: #b11}
|
||||||
|
a:hover {color: #f88}
|
||||||
|
|
||||||
|
pre.code{ font-family: courier new; color: #202060; font-size: 12px; line-height: 14px;}
|
||||||
|
font.code{ font-family: courier new; color: #202060; font-size: 12px; line-height: 14px;}
|
||||||
|
|
88
jasmin/jasmin-2.4/docs/syntax.bnf
Normal file
88
jasmin/jasmin-2.4/docs/syntax.bnf
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
Jasmin Syntax Jonathan Meyer, April 1996
|
||||||
|
|
||||||
|
This file contains a simplified BNF version of the Jasmin syntax.
|
||||||
|
|
||||||
|
jasmin_file ::=
|
||||||
|
'.class' [ <access> ] <name> <break>
|
||||||
|
'.super' <name> <break>
|
||||||
|
[ <fields> ]
|
||||||
|
[ <methods> ]
|
||||||
|
|
||||||
|
|
||||||
|
<fields> ::= <field> [ <field> ... ]
|
||||||
|
|
||||||
|
<field> ::=
|
||||||
|
'.field' <access> <name> <signature> [ = <default> ] <break>
|
||||||
|
|
||||||
|
<default> ::= <int> | <quoted_string> | <float>
|
||||||
|
|
||||||
|
|
||||||
|
<methods> ::= <method> [ <method> ... ]
|
||||||
|
|
||||||
|
<method> ::=
|
||||||
|
'.method' <access> <name> <break>
|
||||||
|
[ <statements> ]
|
||||||
|
'.end' 'method' <break>
|
||||||
|
|
||||||
|
<statements> ::= <statement> [ <statement> ... ]
|
||||||
|
|
||||||
|
<statement> ::=
|
||||||
|
<directive> <break>
|
||||||
|
|
|
||||||
|
<instruction> <break>
|
||||||
|
|
|
||||||
|
<label> ':' <break>
|
||||||
|
|
||||||
|
<directive> ::=
|
||||||
|
'.limit' 'stack' <val>
|
||||||
|
|
|
||||||
|
'.limit' 'locals' <val>
|
||||||
|
|
|
||||||
|
'.throws' <classname>
|
||||||
|
|
|
||||||
|
'.catch' <classname> 'from' <label1> 'to' <label2> 'using' <label3>
|
||||||
|
|
||||||
|
<instruction> ::= <simple_instruction> | <complex_instruction>
|
||||||
|
|
||||||
|
<simple_instruction> ::=
|
||||||
|
<insn>
|
||||||
|
|
|
||||||
|
<insn> <int> <int>
|
||||||
|
|
|
||||||
|
<insn> <int>
|
||||||
|
|
|
||||||
|
<insn> <num>
|
||||||
|
|
|
||||||
|
<insn> <word>
|
||||||
|
|
|
||||||
|
<insn> <word> <int>
|
||||||
|
|
|
||||||
|
<insn> <word> <word>
|
||||||
|
|
|
||||||
|
<insn> <quoted_string>
|
||||||
|
|
||||||
|
<complex_instruction> ::=
|
||||||
|
<lookupswitch>
|
||||||
|
|
|
||||||
|
<tableswitch>
|
||||||
|
|
||||||
|
<lookupswitch> ::=
|
||||||
|
lookupswitch <nl>
|
||||||
|
<int> : <label> <nl>
|
||||||
|
<int> : <label> <nl>
|
||||||
|
...
|
||||||
|
default : <label>
|
||||||
|
|
||||||
|
<tableswitch> ::=
|
||||||
|
tableswitch <low> <nl>
|
||||||
|
<label> <nl>
|
||||||
|
<label> <nl>
|
||||||
|
...
|
||||||
|
default : <label>
|
||||||
|
|
||||||
|
<access> ::= <access_item> [ <access_item> ... ]
|
||||||
|
|
||||||
|
<access_item> ::=
|
||||||
|
'public' | 'private' | 'protected' | 'static' | 'final' |
|
||||||
|
'synchronized' | 'volatile' | 'transient' | 'native' |
|
||||||
|
'interface' | 'abstract'
|
52
jasmin/jasmin-2.4/examples/ANewArray.j
Normal file
52
jasmin/jasmin-2.4/examples/ANewArray.j
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/ANewArray.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Shows how to use anewarray instruction
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; This class demonstrates how to allocate a multidimensional
|
||||||
|
; array using anewarray.
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/ANewArray
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit stack 4
|
||||||
|
.limit locals 2
|
||||||
|
|
||||||
|
;
|
||||||
|
; Allocates an array like:
|
||||||
|
; String x[][] = new String[2][5]
|
||||||
|
;
|
||||||
|
|
||||||
|
; Allocate spine for array and store it in local var 1
|
||||||
|
; (i.e. String[2][])
|
||||||
|
|
||||||
|
iconst_2
|
||||||
|
anewarray [Ljava/lang/String;
|
||||||
|
astore_1
|
||||||
|
|
||||||
|
; allocate first array of String[5] and store it in index 0
|
||||||
|
aload_1
|
||||||
|
iconst_0
|
||||||
|
bipush 5
|
||||||
|
anewarray java/lang/String
|
||||||
|
aastore
|
||||||
|
|
||||||
|
; allocate second array of String[5] and store it in index 1
|
||||||
|
aload_1
|
||||||
|
iconst_1
|
||||||
|
bipush 5
|
||||||
|
anewarray java/lang/String
|
||||||
|
aastore
|
||||||
|
|
||||||
|
; done ...
|
||||||
|
return
|
||||||
|
.end method
|
31
jasmin/jasmin-2.4/examples/AnInterface.j
Normal file
31
jasmin/jasmin-2.4/examples/AnInterface.j
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/AnInterface.j
|
||||||
|
; Author: Jonathan Meyer, 1 Oct 1996
|
||||||
|
; Purpose: A Java interface written in Jasmin
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;
|
||||||
|
; This file shows how to use Jasmin to define an interface. It
|
||||||
|
; is like the Java code:
|
||||||
|
;
|
||||||
|
; interface public examples.AnInterface {
|
||||||
|
; void foo();
|
||||||
|
; }
|
||||||
|
;
|
||||||
|
; See examples.Implementor for an example of a class that implements
|
||||||
|
; this interface.
|
||||||
|
;
|
||||||
|
|
||||||
|
.interface public examples/AnInterface
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
; (Interfaces should either inherit from Object, or from
|
||||||
|
; another interface.)
|
||||||
|
|
||||||
|
;
|
||||||
|
; declare abstract method foo() - note that the method body is empty.
|
||||||
|
;
|
||||||
|
.method abstract foo()V
|
||||||
|
.end method
|
||||||
|
|
||||||
|
|
53
jasmin/jasmin-2.4/examples/Arrays.j
Normal file
53
jasmin/jasmin-2.4/examples/Arrays.j
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/Arrays.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Example using JVM's anewarray and aaload/aastore
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;
|
||||||
|
; This illustrates how to use the various JVM array instructions - though
|
||||||
|
; it doesn't actually do anything very interesting with the arrays.
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/Arrays
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
; standard initializer
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit locals 2
|
||||||
|
.limit stack 4
|
||||||
|
|
||||||
|
; creates a new array of strings,
|
||||||
|
; like:
|
||||||
|
; String[] myarray = new String[2];
|
||||||
|
iconst_2
|
||||||
|
anewarray java/lang/String
|
||||||
|
astore_1 ; stores this in local variable 1
|
||||||
|
|
||||||
|
; this is like the code:
|
||||||
|
; myarray[0] = args[0];
|
||||||
|
|
||||||
|
aload_1 ; push my array on the stack
|
||||||
|
iconst_0
|
||||||
|
aload_0 ; push the array argument to main() on the stack
|
||||||
|
iconst_0
|
||||||
|
aaload ; get its zero'th entry
|
||||||
|
aastore ; and store it in my zero'th entry
|
||||||
|
|
||||||
|
; now print out myarray[0]
|
||||||
|
|
||||||
|
getstatic java/lang/System/out Ljava/io/PrintStream;
|
||||||
|
aload_1
|
||||||
|
iconst_0
|
||||||
|
aaload
|
||||||
|
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
; done
|
||||||
|
return
|
||||||
|
.end method
|
79
jasmin/jasmin-2.4/examples/Catch.j
Normal file
79
jasmin/jasmin-2.4/examples/Catch.j
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/Catch.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Catching and throwing exceptions
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;
|
||||||
|
; This hows how to throw and catch Exceptions in Jasmin
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/Catch
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
; standard initializer
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object.<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
|
||||||
|
.limit locals 3
|
||||||
|
.limit stack 5
|
||||||
|
|
||||||
|
; set up a handler to catch subclasses of java.lang.Exception
|
||||||
|
.catch java/lang/Exception from Label1 to Label2 using Handler
|
||||||
|
|
||||||
|
; store System.out in local variable 1
|
||||||
|
getstatic java/lang/System/out Ljava/io/PrintStream;
|
||||||
|
astore_1
|
||||||
|
|
||||||
|
; print out a message
|
||||||
|
aload_1
|
||||||
|
ldc " -- Before exception"
|
||||||
|
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
; construct an instance of Exception, initialize it with a string,
|
||||||
|
; throw it. This is like the Java statement :
|
||||||
|
;
|
||||||
|
; throw new Exception("My exception");
|
||||||
|
;
|
||||||
|
|
||||||
|
Label1:
|
||||||
|
new java/lang/Exception
|
||||||
|
dup
|
||||||
|
ldc "<my exception>"
|
||||||
|
invokenonvirtual java/lang/Exception/<init>(Ljava/lang/String;)V
|
||||||
|
athrow
|
||||||
|
|
||||||
|
Label2:
|
||||||
|
aload_1
|
||||||
|
ldc " -- After exception"
|
||||||
|
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
; This is the handler for the exception
|
||||||
|
|
||||||
|
Handler:
|
||||||
|
; store the exception in local variable 2
|
||||||
|
astore_2
|
||||||
|
|
||||||
|
; print out a message
|
||||||
|
aload_1
|
||||||
|
ldc " -- Caught exception: "
|
||||||
|
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
; call getMessage() to retrieve the message from the Exception...
|
||||||
|
aload_1
|
||||||
|
aload_2
|
||||||
|
invokevirtual java/lang/Throwable/getMessage()Ljava/lang/String;
|
||||||
|
; ... now print it
|
||||||
|
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
; return to the code
|
||||||
|
goto Label2
|
||||||
|
|
||||||
|
.end method
|
35
jasmin/jasmin-2.4/examples/Checkcast.j
Normal file
35
jasmin/jasmin-2.4/examples/Checkcast.j
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/Checkcast.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Catching and throwing exceptions
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Simple test for checkcast instruction
|
||||||
|
;
|
||||||
|
|
||||||
|
.class examples/Checkcast
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
;
|
||||||
|
; standard initializer
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit stack 2
|
||||||
|
|
||||||
|
; push System.out onto the stack
|
||||||
|
getstatic java/lang/System/out Ljava/io/PrintStream;
|
||||||
|
|
||||||
|
; check that it is a PrintStream
|
||||||
|
checkcast java/io/PrintStream
|
||||||
|
|
||||||
|
; done
|
||||||
|
return
|
||||||
|
.end method
|
56
jasmin/jasmin-2.4/examples/Count.j
Normal file
56
jasmin/jasmin-2.4/examples/Count.j
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/Count.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Counts from 0 to 9, printing out the value
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.class public examples/Count
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
;
|
||||||
|
; standard initializer
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
; set limits used by this method
|
||||||
|
.limit locals 4
|
||||||
|
.limit stack 3
|
||||||
|
|
||||||
|
; setup local variables:
|
||||||
|
|
||||||
|
; 1 - the PrintStream object held in java.lang.System.out
|
||||||
|
getstatic java/lang/System/out Ljava/io/PrintStream;
|
||||||
|
astore_1
|
||||||
|
|
||||||
|
; 2 - the integer 10 - the counter used in the loop
|
||||||
|
bipush 10
|
||||||
|
istore_2
|
||||||
|
|
||||||
|
; now loop 10 times printing out a number
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
|
||||||
|
; compute 10 - <local variable 2> ...
|
||||||
|
bipush 10
|
||||||
|
iload_2
|
||||||
|
isub
|
||||||
|
invokestatic java/lang/String/valueOf(I)Ljava/lang/String;
|
||||||
|
astore_3
|
||||||
|
; ... and print it
|
||||||
|
aload_1 ; push the PrintStream object
|
||||||
|
aload_3 ; push the string we just created - then ...
|
||||||
|
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
; decrement the counter and loop
|
||||||
|
iinc 2 -1
|
||||||
|
iload_2
|
||||||
|
ifne Loop
|
||||||
|
|
||||||
|
; done
|
||||||
|
return
|
||||||
|
|
||||||
|
.end method
|
5
jasmin/jasmin-2.4/examples/HelloWeb.html
Normal file
5
jasmin/jasmin-2.4/examples/HelloWeb.html
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
This shows how to run HelloApplet:<p>
|
||||||
|
|
||||||
|
<applet code="HelloWeb.class" width=350 height=75>
|
||||||
|
</applet>
|
91
jasmin/jasmin-2.4/examples/HelloWeb.j
Normal file
91
jasmin/jasmin-2.4/examples/HelloWeb.j
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/HelloWeb.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Demonstration of a Jasmin-created applet
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
; HelloWeb.j
|
||||||
|
|
||||||
|
; This demonstrates how you can use Jasmin to create an applet.
|
||||||
|
|
||||||
|
; The code below is like the Java code:
|
||||||
|
;
|
||||||
|
; import java.applet.*;
|
||||||
|
; import java.awt.*;
|
||||||
|
;
|
||||||
|
; public class HelloWeb extends Applet {
|
||||||
|
; private Font font;
|
||||||
|
;
|
||||||
|
; public void init() {
|
||||||
|
; font = new Font("Helvetica", Font.BOLD, 48);
|
||||||
|
; }
|
||||||
|
;
|
||||||
|
; public void paint(Graphics g) {
|
||||||
|
; g.setFont(font);
|
||||||
|
; g.drawString("Hello World!", 25, 50);
|
||||||
|
; }
|
||||||
|
; }
|
||||||
|
|
||||||
|
|
||||||
|
.class public HelloWeb
|
||||||
|
.super java/applet/Applet
|
||||||
|
|
||||||
|
.field private font Ljava/awt/Font;
|
||||||
|
|
||||||
|
|
||||||
|
; my init() method - allocate a font and assign it to this.font.
|
||||||
|
|
||||||
|
.method public init()V
|
||||||
|
.limit stack 5
|
||||||
|
|
||||||
|
; Create a new Font and call its constructor with
|
||||||
|
; "Helvetica", 1 (i.e. Font.BOLD), and 48.
|
||||||
|
|
||||||
|
new java/awt/Font
|
||||||
|
dup
|
||||||
|
ldc "Helvetica"
|
||||||
|
iconst_1
|
||||||
|
bipush 48
|
||||||
|
invokenonvirtual java/awt/Font/<init>(Ljava/lang/String;II)V
|
||||||
|
|
||||||
|
; now store the Font on the stack in this.font
|
||||||
|
aload_0
|
||||||
|
swap
|
||||||
|
putfield HelloWeb/font Ljava/awt/Font;
|
||||||
|
|
||||||
|
; done
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
; my paint() method - draws the string "Hello World!" using this.font.
|
||||||
|
|
||||||
|
.method public paint(Ljava/awt/Graphics;)V
|
||||||
|
.limit stack 4
|
||||||
|
.limit locals 2
|
||||||
|
|
||||||
|
; local variable 0 holds <this>
|
||||||
|
; local variable 1 holds the java.awt.Graphics instance ('g').
|
||||||
|
|
||||||
|
; g.setFont(this.font);
|
||||||
|
aload_1
|
||||||
|
aload_0
|
||||||
|
getfield HelloWeb/font Ljava/awt/Font;
|
||||||
|
invokevirtual java/awt/Graphics/setFont(Ljava/awt/Font;)V
|
||||||
|
|
||||||
|
; g.drawString("Hello Web!", 25, 50);
|
||||||
|
aload_1
|
||||||
|
ldc "Hello Web!"
|
||||||
|
bipush 25
|
||||||
|
bipush 50
|
||||||
|
invokevirtual java/awt/Graphics/drawString(Ljava/lang/String;II)V
|
||||||
|
|
||||||
|
; done
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
|
||||||
|
; standard constructor
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/applet/Applet/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
BIN
jasmin/jasmin-2.4/examples/HelloWorld.class
Normal file
BIN
jasmin/jasmin-2.4/examples/HelloWorld.class
Normal file
Binary file not shown.
35
jasmin/jasmin-2.4/examples/HelloWorld.j
Normal file
35
jasmin/jasmin-2.4/examples/HelloWorld.j
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/HelloWorld.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Prints out "Hello World!"
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
.class public NoJad.j
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
;
|
||||||
|
; standard initializer
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit stack 2
|
||||||
|
.limit locals 2
|
||||||
|
|
||||||
|
bipush 2
|
||||||
|
astore 0
|
||||||
|
bipush 3
|
||||||
|
astore 1
|
||||||
|
|
||||||
|
aload 0
|
||||||
|
aload 1
|
||||||
|
astore 0
|
||||||
|
astore 1
|
||||||
|
|
||||||
|
return
|
||||||
|
.end method
|
53
jasmin/jasmin-2.4/examples/Implementor.j
Normal file
53
jasmin/jasmin-2.4/examples/Implementor.j
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/HelloWorld.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Shows how to define a class that implements an interface
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;
|
||||||
|
; This class implements the examples.AnInterface interface - see
|
||||||
|
; AnInterface.j
|
||||||
|
;
|
||||||
|
.class public examples/Implementor
|
||||||
|
.super java/lang/Object
|
||||||
|
.implements examples/AnInterface
|
||||||
|
|
||||||
|
;
|
||||||
|
; standard initializer
|
||||||
|
;
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
;
|
||||||
|
; implement the foo()V method - this is an interface method
|
||||||
|
;
|
||||||
|
.method public foo()V
|
||||||
|
.limit stack 2
|
||||||
|
|
||||||
|
; print a simple message
|
||||||
|
getstatic java/lang/System/out Ljava/io/PrintStream;
|
||||||
|
ldc "Hello Interface"
|
||||||
|
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
|
||||||
|
|
||||||
|
; done
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit stack 2
|
||||||
|
|
||||||
|
; create a new one of me
|
||||||
|
new examples/Implementor
|
||||||
|
dup
|
||||||
|
invokenonvirtual examples/Implementor/<init>()V
|
||||||
|
|
||||||
|
; now call my interface method foo()
|
||||||
|
invokeinterface examples/AnInterface/foo()V 1
|
||||||
|
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
45
jasmin/jasmin-2.4/examples/InvokeInterface.j
Normal file
45
jasmin/jasmin-2.4/examples/InvokeInterface.j
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/InvokeInterface.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Example of using invokeinterface
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; Demonstrates invoking an interface method
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/InvokeInterface
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
; standard initializer
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
;
|
||||||
|
; This is a rather silly example - since the result of calling the
|
||||||
|
; interface method isn't actually used. But it does illustrate how to
|
||||||
|
; use invokeinterface.
|
||||||
|
;
|
||||||
|
|
||||||
|
.method public example(Ljava/util/Enumeration;)V
|
||||||
|
.limit stack 1
|
||||||
|
.limit locals 3
|
||||||
|
|
||||||
|
; push local variable 1 (the Enumeration object)
|
||||||
|
aload_1
|
||||||
|
|
||||||
|
; now call the hasMoreElements() interface method.
|
||||||
|
invokeinterface java/util/Enumeration/hasMoreElements()Z 1
|
||||||
|
|
||||||
|
; store the integer result in local variable 2
|
||||||
|
istore_2
|
||||||
|
|
||||||
|
; done
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
return
|
||||||
|
.end method
|
37
jasmin/jasmin-2.4/examples/MultiANewArray.j
Normal file
37
jasmin/jasmin-2.4/examples/MultiANewArray.j
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/MultiANewArray.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Example of multanewarray instruction
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; This illustrates how to use multianewarray to allocate
|
||||||
|
; an array.
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/MultiANewArray
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
; standard initializer
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
|
||||||
|
.limit locals 4
|
||||||
|
.limit stack 2
|
||||||
|
|
||||||
|
;
|
||||||
|
; This allocates an array like:
|
||||||
|
;
|
||||||
|
; String s[][] = new String[2][5];
|
||||||
|
;
|
||||||
|
iconst_2
|
||||||
|
iconst_5
|
||||||
|
multianewarray [[Ljava/lang/String; 2
|
||||||
|
astore_1
|
||||||
|
|
||||||
|
return
|
||||||
|
.end method
|
55
jasmin/jasmin-2.4/examples/MultiArrays.j
Normal file
55
jasmin/jasmin-2.4/examples/MultiArrays.j
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/MultiArrays.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Examples involving multi-dimensional arrays
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; This illustrates how to use multi-dimensional arrays in the Java VM
|
||||||
|
; (though it doesn't actually do anything very interesting with the arrays.)
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/MultiArrays
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
; standard initializer
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
|
||||||
|
.limit locals 4
|
||||||
|
.limit stack 5
|
||||||
|
|
||||||
|
; this is like:
|
||||||
|
; new int[2][5][]
|
||||||
|
iconst_2
|
||||||
|
iconst_5
|
||||||
|
multianewarray [[[I 2
|
||||||
|
|
||||||
|
; store the result in local variable 1
|
||||||
|
astore_1
|
||||||
|
|
||||||
|
aload_1
|
||||||
|
iconst_1
|
||||||
|
aaload ; stack now contains x[0]
|
||||||
|
astore_2 ; store the array in local variable 2
|
||||||
|
|
||||||
|
; create a new array of 50 ints and store it in x[1][1]
|
||||||
|
aload_2
|
||||||
|
iconst_1
|
||||||
|
bipush 50
|
||||||
|
newarray int
|
||||||
|
aastore
|
||||||
|
|
||||||
|
; create a new array of 60 ints and store it in x[1][2]
|
||||||
|
aload_2
|
||||||
|
iconst_2
|
||||||
|
bipush 60
|
||||||
|
newarray int
|
||||||
|
aastore
|
||||||
|
|
||||||
|
return
|
||||||
|
.end method
|
41
jasmin/jasmin-2.4/examples/NewArray.j
Normal file
41
jasmin/jasmin-2.4/examples/NewArray.j
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/NewArray.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Example of newarray
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; Example showing how to allocate an array using
|
||||||
|
; newarray.
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/NewArray
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit stack 4
|
||||||
|
.limit locals 2
|
||||||
|
|
||||||
|
; create an array like:
|
||||||
|
;
|
||||||
|
; boolean b[] = new boolean[2]
|
||||||
|
;
|
||||||
|
; (stores it in local var 1)
|
||||||
|
|
||||||
|
iconst_2
|
||||||
|
newarray boolean
|
||||||
|
astore_1
|
||||||
|
|
||||||
|
; b[0] = true;
|
||||||
|
aload_1
|
||||||
|
iconst_0
|
||||||
|
iconst_1
|
||||||
|
bastore
|
||||||
|
|
||||||
|
return
|
||||||
|
.end method
|
41
jasmin/jasmin-2.4/examples/Switch.j
Normal file
41
jasmin/jasmin-2.4/examples/Switch.j
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/Switch.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Shows usage of lookupswitch and tableswitch
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;
|
||||||
|
; Illustrates lookupswitch and tableswitch syntax for Jasmin
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/Switch
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit stack 3
|
||||||
|
|
||||||
|
iconst_1
|
||||||
|
lookupswitch
|
||||||
|
1 : Hello
|
||||||
|
2 : Goodbye
|
||||||
|
default : Foo
|
||||||
|
|
||||||
|
iconst_1
|
||||||
|
tableswitch 0
|
||||||
|
Hello
|
||||||
|
Goodbye
|
||||||
|
default : Foo
|
||||||
|
|
||||||
|
Hello:
|
||||||
|
Goodbye:
|
||||||
|
Foo:
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
.end method
|
36
jasmin/jasmin-2.4/examples/Uncaught.j
Normal file
36
jasmin/jasmin-2.4/examples/Uncaught.j
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/Uncaught.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Throws an exception - doesn't catch it
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;
|
||||||
|
; This example class contains a main() method that throws
|
||||||
|
; an exception but doesn't catch it -
|
||||||
|
;
|
||||||
|
.source Uncaught.j
|
||||||
|
.class public examples/Uncaught
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
; specify the initializer method (as for HelloWorld)
|
||||||
|
|
||||||
|
.method public <init>()V
|
||||||
|
; just call Object's initializer
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
; specify the "main" method - this throws an uncaught exception
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
.limit stack 2
|
||||||
|
|
||||||
|
new java/lang/Exception
|
||||||
|
dup
|
||||||
|
invokenonvirtual java/lang/Exception/<init>()V
|
||||||
|
athrow
|
||||||
|
|
||||||
|
; without this the verifier might complain ...
|
||||||
|
return
|
||||||
|
.end method
|
41
jasmin/jasmin-2.4/examples/VerifyTest.j
Normal file
41
jasmin/jasmin-2.4/examples/VerifyTest.j
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/VerifyTest.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Treats an int as an object - should alert the Verifier
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;
|
||||||
|
; This code demonstrates the verifier at work. See also VerifyTest1.j.
|
||||||
|
;
|
||||||
|
; The main() method below tries to clone the integer 100 - this
|
||||||
|
; is clearly an error since clone() expects an Object, not an integer.
|
||||||
|
;
|
||||||
|
; If you run this with no verification on, it is likely to crash the
|
||||||
|
; interpreter. Running this with the -verify option produces a
|
||||||
|
; Verifier error.
|
||||||
|
;
|
||||||
|
|
||||||
|
; This is similar to the Java code:
|
||||||
|
;
|
||||||
|
; class VerifyTest {
|
||||||
|
; public static void main(String args[]) {
|
||||||
|
; int x = 100;
|
||||||
|
; x.clone();
|
||||||
|
; }
|
||||||
|
; }
|
||||||
|
|
||||||
|
|
||||||
|
.class public examples/VerifyTest
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
bipush 100
|
||||||
|
invokevirtual java/lang/Object/clone()Ljava/lang/Object;
|
||||||
|
return
|
||||||
|
.end method
|
62
jasmin/jasmin-2.4/examples/VerifyTest1.j
Normal file
62
jasmin/jasmin-2.4/examples/VerifyTest1.j
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
; --- Copyright Jonathan Meyer 1996. All rights reserved. -----------------
|
||||||
|
; File: jasmin/examples/VerifyTest1.j
|
||||||
|
; Author: Jonathan Meyer, 10 July 1996
|
||||||
|
; Purpose: Trys to pull one on the verifier
|
||||||
|
; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
; This file illustrates the bytecode verifier at work - the
|
||||||
|
; code in the example() method below seems reasonable, but
|
||||||
|
; Java's bytecode verifier will fail the code because the two points leading
|
||||||
|
; to the Loop label (from the top of the method and from the ifne
|
||||||
|
; statement) have different stack states. Instead, a different approach
|
||||||
|
; must be adopted - e.g. by allocating an array, or simply writing:
|
||||||
|
;
|
||||||
|
; aconst_null
|
||||||
|
; aconst_null
|
||||||
|
; aconst_null
|
||||||
|
; aconst_null
|
||||||
|
|
||||||
|
; Note that many interpreters will run this code OK if you don't use
|
||||||
|
; a verifier. The code itself is well behaved (it doesn't trash the
|
||||||
|
; interpreter), but the approach it uses is disallowed by the verifier.
|
||||||
|
;
|
||||||
|
|
||||||
|
; Compile the example, then run it using:
|
||||||
|
;
|
||||||
|
; % java -verify VerifyTest1
|
||||||
|
; VERIFIER ERROR VerifyTest1.example()V:
|
||||||
|
; Inconsistent stack height 1 != 0
|
||||||
|
;
|
||||||
|
|
||||||
|
.class public examples/VerifyTest1
|
||||||
|
.super java/lang/Object
|
||||||
|
|
||||||
|
.method public <init>()V
|
||||||
|
aload_0
|
||||||
|
invokenonvirtual java/lang/Object/<init>()V
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public example()V
|
||||||
|
.limit locals 2
|
||||||
|
.limit stack 10
|
||||||
|
|
||||||
|
; this tries to push four nulls onto the stack
|
||||||
|
; using a loop - Java's verifier will fail this program
|
||||||
|
|
||||||
|
iconst_4 ; store 4 in local variable 1 (used as a counter)
|
||||||
|
istore_1
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
aconst_null ; push null onto the stack
|
||||||
|
iinc 1 -1 ; decrement local variable 4 (the counter variable)
|
||||||
|
iload_1
|
||||||
|
ifne Loop ; jump back to Loop unless the variable has reached 0
|
||||||
|
|
||||||
|
return
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static main([Ljava/lang/String;)V
|
||||||
|
; - do nothing : this is only to illustrate the bytecode verifier at work.
|
||||||
|
return
|
||||||
|
.end method
|
BIN
jasmin/jasmin-2.4/html2x/jasmin_icon.jpg
Normal file
BIN
jasmin/jasmin-2.4/html2x/jasmin_icon.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
16
jasmin/jasmin-2.4/html2x/style.css
Normal file
16
jasmin/jasmin-2.4/html2x/style.css
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
td { font-family: Verdana,Arial,Helvetica,sans-serif; color: #000000; font-size: 12px; line-height: 16px; }
|
||||||
|
td h1 { font-family: Tahoma; padding: 1px; padding-left: 4px; color: white; background-color: #303030; font-size: 20px; line-height: 24px; font-weight: bold; }
|
||||||
|
td h2{ font-family: Tahoma; color: #000000; font-size: 14px; line-height: 16px; font-weight: bold; }
|
||||||
|
td h3 { font-family: Tahoma; color: #000000; font-size: 12px; line-height: 16px; font-weight: bold; }
|
||||||
|
|
||||||
|
.h1 { font-family: Times; color: #000000; font-size: 18px; line-height: 20px; font-weight: bold; }
|
||||||
|
|
||||||
|
/* main text hyperlinks */
|
||||||
|
a { color: #b11; TEXT-DECORATION: underline; }
|
||||||
|
a:visited {color: #b11}
|
||||||
|
a:hover {color: #f88}
|
||||||
|
|
||||||
|
pre.code{ font-family: courier new; color: #202060; font-size: 12px; line-height: 14px;}
|
||||||
|
font.code{ font-family: courier new; color: #202060; font-size: 12px; line-height: 14px;}
|
||||||
|
|
414
jasmin/jasmin-2.4/html2x/xt.html
Normal file
414
jasmin/jasmin-2.4/html2x/xt.html
Normal file
|
@ -0,0 +1,414 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Jasmin User Guide</title>
|
||||||
|
<link href="style.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr><td width=550>
|
||||||
|
<center>
|
||||||
|
<p><img src=jasmin_icon.jpg></p>
|
||||||
|
<p>
|
||||||
|
<div class="h1">JasminXT Syntax</div>
|
||||||
|
Daniel Reynaud, Mart 2006
|
||||||
|
</p>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<h1>About This Document</h1>
|
||||||
|
|
||||||
|
This guide describes the rules and syntax used in JasminXT, the extension of
|
||||||
|
the Jasmin language in version 2.0. If you are new to Jasmin, you should
|
||||||
|
refer to the Jasmin user guide. Note that this document doesn't
|
||||||
|
explain the Java Virtual Machine itself, or give syntax notes for
|
||||||
|
every instruction known to Jasmin. See the Java Virtual Machine specification
|
||||||
|
for more information on the JVM.<p>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>Why a new Jasmin language ?</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Jasmin is the de-facto standard Java assembly language. It is useful to explore
|
||||||
|
the possibilities of bytecode, but it does not offer a real low level control
|
||||||
|
over the produced output. Therefore it is not suitable to generate test cases
|
||||||
|
for virtual machines or bytecode verifier. This new version of the Jasmin
|
||||||
|
language, called JasminXT, provides optional directives and other syntax
|
||||||
|
updates to have more control over the output and to stick with the latest
|
||||||
|
changes of the Java language.</p>
|
||||||
|
|
||||||
|
<p>JasminXT has been defined for the tinapoc project. The purpose of the tinapoc
|
||||||
|
project is to create a reliable Java reverse engineering toolkit. See the tinapoc
|
||||||
|
homepage for more information : <a href="http://tinapoc.sourceforge.net/">http://tinapoc.sourceforge.net/</a></p>
|
||||||
|
|
||||||
|
<h1>Summary of the new features</h1>
|
||||||
|
<p>
|
||||||
|
<b>Since 2.4 :</b><br>
|
||||||
|
<li> accept 'd'-suffix in float constant (no attempt cast to float)
|
||||||
|
<li> redesign to dynamic compiler class creation
|
||||||
|
<li> some cosmetic bugfixes
|
||||||
|
<br><br>
|
||||||
|
<b>Since 2.3 :</b><br>
|
||||||
|
<li> added 'wide'-aliases to two-face instructions
|
||||||
|
<br><br>
|
||||||
|
<b>Since 2.2 :</b><br>
|
||||||
|
<li> some bug fixes in the diagnostic
|
||||||
|
<li> added support for attribute StackMapTable (directive .stack) described in JDK1.6
|
||||||
|
<li> added keyword 'use' to directive .stack
|
||||||
|
<li> added support for \uXXXX escape sequence in the names (just as in the Java)
|
||||||
|
<li> instruction ldc_w always generates wide index
|
||||||
|
<li> changed syntaxes of the non-standard identifiers (or overloaded keywords), now it hasto be signgle quoted and can't be empty
|
||||||
|
<br><br>
|
||||||
|
<b>Since 2.1 :</b><br>
|
||||||
|
<li> some bug fixes with string and number parsing
|
||||||
|
<li> added support for \uXXXX escape sequences
|
||||||
|
<li> added support for access flags ACC_STRICT (fpstrict) and ACC_SYNTHETIC (synthetic)
|
||||||
|
<li> added signatures for local variables support
|
||||||
|
<li> several .debug directives are permitted
|
||||||
|
<li> added the invokedynamic instruction
|
||||||
|
<li> improved the syntax of the StackMap attribute (.stack directive)
|
||||||
|
<li> new command-line option -e to support different encodings
|
||||||
|
<li> added support for non-standard identifiers in double-quotes
|
||||||
|
<li> fields can now be defined on multiple lines
|
||||||
|
<li> new directives have been included : .inner, .attribute, .deprecated, .annotation
|
||||||
|
<br><br>
|
||||||
|
<b>Since 2.0 :</b><br><br>
|
||||||
|
<li>use of offsets for branch targets, local variable visibility and exception handlers. The offsets can either be absolute or relative :<br>
|
||||||
|
<pre>
|
||||||
|
goto 12 ; absolute offset : go to bytecode at offset 12
|
||||||
|
goto +5 ; relative offset : go 12 bytes forward
|
||||||
|
goto -8 ; relative offset : go 8 bytes backwards
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<li>the following access flags are now supported : ACC_ENUM, ACC_ANNOTATION, ACC_BRIDGE and ACC_VARARGS<br>
|
||||||
|
|
||||||
|
<li>the .bytecode directive has been added, to set the bytecode version in the class file.<br>
|
||||||
|
Example : <pre>.bytecode 49.0</pre><br>
|
||||||
|
|
||||||
|
<li>it is now possible to add a SourceDebugExtension attribute to the class with the following directive :<br>
|
||||||
|
<pre>.debug "some string here"</pre><br>
|
||||||
|
|
||||||
|
<li>same thing for the EnclosingMethod attribute :<br>
|
||||||
|
<pre>.enclosing method "some/package/Foo/someMethod(I)V"</pre><br>
|
||||||
|
|
||||||
|
<li>support for the Signature attribute (in the classes, methods and fields) :<br>
|
||||||
|
<pre>.signature "<my::own>Signature()"
|
||||||
|
.field myField Ljava/lang/String; signature "<my::own>Signature()"</pre><br>
|
||||||
|
|
||||||
|
<li>support for the StackMap attribute, using the .stack directive in a method definition<br>
|
||||||
|
|
||||||
|
<li>it is now possible to give the offset of an instruction before the instruction itself, like in the following code snippet :<br>
|
||||||
|
<pre>
|
||||||
|
0: aload_0
|
||||||
|
1: invokespecial java/lang/Object/<init>()V
|
||||||
|
4: aload_0
|
||||||
|
5: ldc2_w 3.14159
|
||||||
|
</pre>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h1>JasminXT File Format</h1>
|
||||||
|
<p>
|
||||||
|
This new version is an extension of the existing Jasmin language, therefore old
|
||||||
|
Jasmin files should still compile correctly with newer versions of Jasmin.
|
||||||
|
JasminXT is supported by Jasmin 2.0 or higher. <b>Changes in Jasmin 2.4 are in bold.</b></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In the rest of this document, words between '[' and ']' are optional. The
|
||||||
|
syntax of a JasminXT file is the following :</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<jas_file> {
|
||||||
|
<jasmin_header>
|
||||||
|
[<field>]*
|
||||||
|
[<method>]*
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h1>JasminXT Header</h1>
|
||||||
|
<pre>
|
||||||
|
<jasmin_header> {
|
||||||
|
[.bytecode <x.y>]
|
||||||
|
[.source <sourcefile>]
|
||||||
|
<class_spec>
|
||||||
|
<super_spec>
|
||||||
|
<implements>
|
||||||
|
[.signature "<signature>"]
|
||||||
|
[.enclosing method <method_name>]
|
||||||
|
[.debug "<debug_source_extension>"]*
|
||||||
|
[.inner class [<access>] [<name>] [inner <classname>] [outer <name>]]*
|
||||||
|
[.inner interface [<access>] [<name>] [inner <classname>] [outer <name>]]*
|
||||||
|
}
|
||||||
|
|
||||||
|
example :
|
||||||
|
.bytecode 49.0
|
||||||
|
.source hello.j
|
||||||
|
.class hello
|
||||||
|
.super java/lang/Object
|
||||||
|
.signature "<my::own>Signature()"
|
||||||
|
.enclosing method foo/bar/Whatever/someMethod()</pre>
|
||||||
|
.debug "this string will be included in the SourceDebugExtension attribute"
|
||||||
|
.debug "this string too"
|
||||||
|
|
||||||
|
<p>The .bytecode directive sets the version of the bytecode in the class file.</p>
|
||||||
|
|
||||||
|
<p>The .signature directive, when used in the header of the Jasmin file, sets the
|
||||||
|
Signature attribute for the class (the argument is a string between double
|
||||||
|
quotes)</p>
|
||||||
|
|
||||||
|
<p>The .enclosing directive sets the EnclosingMethod attribute for the class. The
|
||||||
|
argument is a supposed to be a method name, but it can be any string between
|
||||||
|
double quotes.</p>
|
||||||
|
|
||||||
|
<p>The .debug directive sets the SourceDebugExtension attribute for the class (the
|
||||||
|
argument is also a string between double quotes)</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h1>JasminXT Class, Super Class and Interfaces Definition</h1>
|
||||||
|
<pre>
|
||||||
|
<class_spec> {
|
||||||
|
.class <access_spec> <class_name>
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>where <access_spec> is any number of words taken from this list : public,
|
||||||
|
private, protected, static, final, synchronized, native, final, super,
|
||||||
|
interface, abstract, annotation, enum, bridge/volatile, transient/varargs</p>
|
||||||
|
|
||||||
|
<p>and <class_name> is the fully qualified internal form of the class, such as
|
||||||
|
my/package/MyClass</p><br>
|
||||||
|
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<super_spec> {
|
||||||
|
.super <class_name>
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<implements> {
|
||||||
|
.implements <class_name>*
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
The .super and .implements directives have not been modified in JasminXT<br>
|
||||||
|
The .implements directive can be repeated in order to implement multiple interfaces</p><br>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h1>JasminXT Field Definition</h1>
|
||||||
|
<pre>
|
||||||
|
<field> {
|
||||||
|
.field <access_spec> <field_name> <descriptor> [signature <signature>]
|
||||||
|
[ = <value> ]
|
||||||
|
|
|
||||||
|
.field <access_spec> <field_name> <descriptor> [signature <signature>]
|
||||||
|
[ = <value> ]
|
||||||
|
[<field_attribute>]*
|
||||||
|
.end field
|
||||||
|
(...)
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
If present, the Signature attribute will be set in the class file for this field with the given
|
||||||
|
quoted string as an argument.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<field_attribute> {
|
||||||
|
.deprecated
|
||||||
|
| .attribute <name> <file_name>
|
||||||
|
| .signature <signature>
|
||||||
|
| .annotation (...)
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
(see below for the definition of the annotation and the attribute directives)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>examples :
|
||||||
|
<pre>.field enum myField Ljava/lang/String; signature "<my::own>Signature()" = "val"</pre>
|
||||||
|
<pre>.field static hello_string Ljava/lang/String;
|
||||||
|
.signature "mySignature"
|
||||||
|
.deprecated
|
||||||
|
.end field</pre>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>JasminXT Method Definition</h1>
|
||||||
|
The general format of a method definition has not changed in JasminXT.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<method> {
|
||||||
|
.method <access_spec> <method_name> <descriptor>
|
||||||
|
<statement>*
|
||||||
|
.end method
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>JasminXT Method Statements</h1>
|
||||||
|
<pre>
|
||||||
|
<statement> {
|
||||||
|
.limit stack <integer>
|
||||||
|
| .limit locals <integer>
|
||||||
|
| .line <integer>
|
||||||
|
| .var <var_number> is <var_name> <descriptor> [signature <sign>] from <label1> to <label2>
|
||||||
|
| .var <var_number> is <var_name> <descriptor> [signature <sign>] from <offset1> to <offset2>
|
||||||
|
| .throws <classname>
|
||||||
|
| .catch <classname> from <label1> to <label2> using <label3>
|
||||||
|
| .catch <classname> from <offset1> to <offset2> using <offset3>
|
||||||
|
| .signature "<signature>"
|
||||||
|
| .stack
|
||||||
|
[offset {<pc> | <label>}]
|
||||||
|
[locals <verification_type> [<verification_arg>]]
|
||||||
|
(...)
|
||||||
|
[stack <verification_type> [<verification_arg>]]
|
||||||
|
(...)
|
||||||
|
.end stack
|
||||||
|
| .stack use [n] locals
|
||||||
|
(...)
|
||||||
|
.end stack
|
||||||
|
| <instruction> [<instruction_args>]
|
||||||
|
| <Label>:
|
||||||
|
| .deprecated
|
||||||
|
| <generic> ; see below for the use of generic attributes
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
In Jasmin XT you can now use offsets instead of labels for the local variable
|
||||||
|
definitions and for the exception handlers definitions.</p>
|
||||||
|
|
||||||
|
<p>The .signature sets the Signature attribute for this method with the given
|
||||||
|
quoted string.<p>
|
||||||
|
|
||||||
|
<p>You can now also define StackMap (or StackMapTable) attributes using
|
||||||
|
the .stack directive. <pc> is an offset in the local bytecode array.
|
||||||
|
<verification_type> is one of the following keywords : Top, Integer,
|
||||||
|
Float, Long, Double, Null, UninitializedThis, Object or Uninitialized. Object
|
||||||
|
takes a <classname> as a parameter. Uninitialized takes an integer or a
|
||||||
|
label as a parameter. Also, jasmin allows to use "short" notation. The
|
||||||
|
'.stack use [n] locals' directive results in copy first <n> values from
|
||||||
|
previous .stack directive. If <n> is omitted, all values are copied.</p>
|
||||||
|
|
||||||
|
<p>NOTE: If bytecode version is 50 or above jasmin generates StackMapTable
|
||||||
|
attribute in accordance with specification of the new 'ClassFile Format'
|
||||||
|
edition. If bytecode version is 49 or below jasmin generate StakMap attribute
|
||||||
|
in accordance with CLDC specification.<p>
|
||||||
|
|
||||||
|
examples :
|
||||||
|
<pre>
|
||||||
|
.stack
|
||||||
|
offset 16
|
||||||
|
locals Null
|
||||||
|
locals Top
|
||||||
|
locals Object allo
|
||||||
|
stack Uninitialized 12
|
||||||
|
.end stack
|
||||||
|
|
||||||
|
.stack
|
||||||
|
; offset is not specified, the offset of the current opcode will be used
|
||||||
|
locals Null
|
||||||
|
locals Top
|
||||||
|
locals Object allo
|
||||||
|
stack Uninitialized Label0
|
||||||
|
.end stack
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
This statement defines a single stack map frame. All the stack map frames
|
||||||
|
defined in a method are then aggregated and form the StackMap attribute for the
|
||||||
|
method. The last example my be wrote at the short notation as:</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
.stack use locals
|
||||||
|
stack Uninitialized Label0
|
||||||
|
.end stack
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h1>JasminXT Instructions</h1>
|
||||||
|
<pre>
|
||||||
|
<instruction> {
|
||||||
|
[<pc>:] <opcode> [<instruction_args>]
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The main change in JasminXT is that it is now possible to put the offset of the
|
||||||
|
instruction before the opcode (the <pc>: statement). The pc is processed as a
|
||||||
|
label, therefore you can virtually put any number as the pc but it won't change
|
||||||
|
the actual pc of the bytecode.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Another update is that it is now possible to use offsets (both relative and
|
||||||
|
absolute) as branch targets instead of labels. The offset is considered to be
|
||||||
|
relative if it begins with '$+' or '$-'.</p>
|
||||||
|
|
||||||
|
example :
|
||||||
|
<pre>
|
||||||
|
goto n ; absolute offset : go to the bytecode labelled n
|
||||||
|
goto $+n ; relative offset : go n bytes forward (from the offset of this goto)
|
||||||
|
goto $-n ; relative offset : go n bytes backwards
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If something hasn't been documented here, it means that it hasn't changed, so
|
||||||
|
you can still refer to the Jasmin <a href="guide.html">user guide</a></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Added '_w' aliase to [adfli]-load/store, iinc and ret instructions (e.g. aload - aload_w).
|
||||||
|
Using '_w' postfix guarantees wide-form of byte-code generation</b></p>
|
||||||
|
|
||||||
|
<h1>Generic Attributes</h1>
|
||||||
|
Generic attributes are supported in class/field/method definitions as follows :
|
||||||
|
<pre><generic> = {
|
||||||
|
.attribute <name> <file_name>
|
||||||
|
}</pre>
|
||||||
|
|
||||||
|
<name> is the name of the attribute and <file_name> is the name of the file containing the data of the attribute (between double quotes). If the generic attribute is in the body of the method, the following logic is used : if it is the first statement in the method, the attribute will be added as a method attribute, otherwise it will be added as a Code attribute.
|
||||||
|
|
||||||
|
<h1>Annotations</h1>
|
||||||
|
Thanks to Iouri Kharon for implementing this. Here are his explanations :<br>
|
||||||
|
|
||||||
|
<p>Added a new directive .annotation to create the AnnotationDefault,
|
||||||
|
RuntimeVisibleAnnotation, RuntimeInvisibleAnnotation,
|
||||||
|
RuntimeVisibeParameterAnnotation, RuntimeInvisibleParameterAnnotation
|
||||||
|
attributes. The directive arguments are verified to have valid values
|
||||||
|
and correct signatures.<br>
|
||||||
|
Complex (nested) annotations are supported as well as arrays of them.<br>
|
||||||
|
The generic format is:
|
||||||
|
<pre>
|
||||||
|
<annotation> = {
|
||||||
|
.annotation visible <classname>
|
||||||
|
| .annotation invisible <classname>>
|
||||||
|
| .annotation visibleparam <paramnum> <classname>
|
||||||
|
| .annotation invisibleparam <paramnum> <classname>
|
||||||
|
| .annotation default
|
||||||
|
........
|
||||||
|
.end annotation
|
||||||
|
|
||||||
|
Field format (except AnnotationDefault):
|
||||||
|
|
||||||
|
<name> <signchar> = <value>*
|
||||||
|
| <name> @ = .annotation
|
||||||
|
........
|
||||||
|
.end annotation
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
AnnotationDefault supports only one field and the <name> tag is not used.
|
||||||
|
Nested annotations must be with the <name> tag and can have any number
|
||||||
|
of fields. Besides, 'empty annotation' is forbidden for AnnotationDefault.
|
||||||
|
Lastly, AnnotationDefault can be used only once for each method.
|
||||||
|
Other annotation types can be used many times and will accumulate information.</p>
|
||||||
|
|
||||||
|
<hr><address>Copyright (c) Daniel Reynaud, Mart 2006</address>
|
||||||
|
<hr>
|
||||||
|
<a href="http://jasmin.sourceforge.net">Jasmin Home</a>
|
||||||
|
</td></tr></table>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
jasmin/jasmin-2.4/jasmin.jar
Normal file
BIN
jasmin/jasmin-2.4/jasmin.jar
Normal file
Binary file not shown.
BIN
jasmin/jasmin-2.4/lib/ant-launcher.jar
Normal file
BIN
jasmin/jasmin-2.4/lib/ant-launcher.jar
Normal file
Binary file not shown.
BIN
jasmin/jasmin-2.4/lib/ant.jar
Normal file
BIN
jasmin/jasmin-2.4/lib/ant.jar
Normal file
Binary file not shown.
13
jasmin/jasmin-2.4/lib/jas/JASMIN_NOTES.txt
Normal file
13
jasmin/jasmin-2.4/lib/jas/JASMIN_NOTES.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
10 October 2004, Jon Meyer
|
||||||
|
|
||||||
|
* Moved the jas src code into ../src/jas.
|
||||||
|
|
||||||
|
|
||||||
|
1 March 1997, Jon Meyer
|
||||||
|
|
||||||
|
* Modified JAS to use self-contained RuntimeConstants interface.
|
||||||
|
|
||||||
|
* Moved JAS classes into the Jasmin classes directory.
|
||||||
|
|
||||||
|
* Fixed bug in CatchEntry.
|
||||||
|
|
109
jasmin/jasmin-2.4/lib/jas/README.txt
Normal file
109
jasmin/jasmin-2.4/lib/jas/README.txt
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
This is v0.3 of a simple Java bytecode assembler.
|
||||||
|
|
||||||
|
|
||||||
|
Quick Info:
|
||||||
|
-----------
|
||||||
|
If you want to just quickly check out things, do the following.
|
||||||
|
|
||||||
|
% java scm.driver examples/hworld.jas
|
||||||
|
|
||||||
|
This compiles an assembler script to bytecode.
|
||||||
|
|
||||||
|
% java out
|
||||||
|
|
||||||
|
This runs the resultant bytecode, which should print the
|
||||||
|
string "Hello World" 5 times.
|
||||||
|
|
||||||
|
|
||||||
|
Then read the online documentation at
|
||||||
|
|
||||||
|
http://www.blackdown.org/~kbs/jas.html
|
||||||
|
|
||||||
|
More Details:
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* What is available:
|
||||||
|
|
||||||
|
A simple java bytecode assembler that can be used either as a
|
||||||
|
standalone scripting program or directly from java (through the jas
|
||||||
|
package)
|
||||||
|
|
||||||
|
* What is not available in this version:
|
||||||
|
|
||||||
|
- Error recovery in the scripting interface
|
||||||
|
- defining a tableswitch or lookupswitch instruction from the scripting
|
||||||
|
interface
|
||||||
|
|
||||||
|
* Documentation
|
||||||
|
|
||||||
|
You can leaf through the jas API in reference/jas You can look at
|
||||||
|
the list of available scripting functions from reference/scm. The
|
||||||
|
bulk of what documentation exists is online from
|
||||||
|
|
||||||
|
http://www.blackdown.org/~kbs/jas.html
|
||||||
|
|
||||||
|
UTSL, ofcourse ;-) And documentation is mostly demand-driven,
|
||||||
|
if there is interest I'll continue to expand it.
|
||||||
|
|
||||||
|
* Examples
|
||||||
|
|
||||||
|
The examples directory contains a few examples of using the
|
||||||
|
assembler with the script and directly from java. Look at the
|
||||||
|
README in this directory to see how to run them. Online
|
||||||
|
documentation contains more details.
|
||||||
|
|
||||||
|
simple.java
|
||||||
|
simple.jas
|
||||||
|
These are simple programs that create classes which
|
||||||
|
don't do anything but get initialized.
|
||||||
|
|
||||||
|
hworld.java
|
||||||
|
hworld.jas
|
||||||
|
These create bytecode that can be run standalone,
|
||||||
|
which print a string a few times.
|
||||||
|
|
||||||
|
exprcomp.java
|
||||||
|
This is a primitive compiler that does runtime
|
||||||
|
codegeneration and execution of arithmetic expressions.
|
||||||
|
exprcomp.jas
|
||||||
|
This is a primitive compiler written in jas to translate
|
||||||
|
jas arithmetic expressions to bytecode.
|
||||||
|
|
||||||
|
* Recompiling
|
||||||
|
|
||||||
|
You can recompile all classes if you wish. First remove the
|
||||||
|
jas/ and the scm/ directories under this directory. Then run the
|
||||||
|
script compile.sh in this directory.
|
||||||
|
|
||||||
|
You will probably want to then run the tests in the test directory
|
||||||
|
to make sure the basic api is functional. Look at the README in this
|
||||||
|
directory for details.
|
||||||
|
|
||||||
|
|
||||||
|
Running the scripting driver:
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
If you are going to use the scripting language, the driver for it is
|
||||||
|
located in the class scm.driver. The magic incantation is
|
||||||
|
|
||||||
|
% java scm.driver [path to file]
|
||||||
|
|
||||||
|
If you don't give it a file name, it will try to read from stdin.
|
||||||
|
|
||||||
|
|
||||||
|
Using code from this distribution:
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
There is exactly one class that I *use* from the sun/* package, which
|
||||||
|
is sun.tools.java.RuntimeConstants. I know of no other reasonable way
|
||||||
|
to keep in sync with the VM.
|
||||||
|
|
||||||
|
Outside of this class, (which is not present in this distribution) you
|
||||||
|
can freely use/modify/sell/dance on with hobnailed boots any or all of
|
||||||
|
this code. If you do end up using derived code and feel disinclined to
|
||||||
|
buy me a snowboard :) all I ask is that you add me to the list of
|
||||||
|
credits.
|
||||||
|
|
||||||
|
-KB-
|
||||||
|
kbs@sbktech.org
|
||||||
|
Version created: Tue Aug 21 09:50:23 PDT 1996
|
52
jasmin/jasmin-2.4/lib/jas/examples/README
Normal file
52
jasmin/jasmin-2.4/lib/jas/examples/README
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
This contains three examples of using the assembler
|
||||||
|
from java and from the script
|
||||||
|
|
||||||
|
Look up http://www.blackdown.org/~kbs/jas.html for more
|
||||||
|
documentation. This only tells you how to run the examples. The
|
||||||
|
documentation is very Unix centric, I apologize.... I have not had
|
||||||
|
time to set this up on the PC's yet.
|
||||||
|
|
||||||
|
|
||||||
|
simple.java:
|
||||||
|
simple.jas:
|
||||||
|
|
||||||
|
Unexciting program that generates a do nothing class.
|
||||||
|
|
||||||
|
Go up a directory and compile simple.java. Run the program,
|
||||||
|
which generates the bytecode. Disassemble the bytecode
|
||||||
|
|
||||||
|
% (cd ..; javac -d . examples/simple.java; java simple; javap -p -c out)
|
||||||
|
|
||||||
|
Same thing, but using the script instead of java directly.
|
||||||
|
|
||||||
|
% (cd ..; java scm.driver examples/simple.jas; javap -p -c out)
|
||||||
|
|
||||||
|
|
||||||
|
hworld.java:
|
||||||
|
hworld.jas:
|
||||||
|
|
||||||
|
Print a string in a loop.
|
||||||
|
|
||||||
|
% (cd ..; javac -d . examples/hworld.java; java hworld; java out)
|
||||||
|
|
||||||
|
As before, but use script instead.
|
||||||
|
|
||||||
|
% (cd ..; java scm.driver examples/hworld.jas; java out)
|
||||||
|
|
||||||
|
exprcomp.java:
|
||||||
|
|
||||||
|
Primitive runtime expression compiler. It translates arithmetic
|
||||||
|
expressions into bytecode and loads it on the fly as a class, which
|
||||||
|
is run to get the answer. test.inp is an example of the sort of
|
||||||
|
arithmetic expressions it translates.
|
||||||
|
|
||||||
|
% (cd ..; javac -d . examples/exprcomp.java; java exprcomp examples/test.inp)
|
||||||
|
|
||||||
|
exprcomp.jas:
|
||||||
|
|
||||||
|
Primitive compiler for jas arithmetic expressions (in jas).
|
||||||
|
jas is fairly expressive, thats about the only point of this
|
||||||
|
exercise ;-) Unlike the java version, this gets written out
|
||||||
|
into a file which you'll have to run to get the results.
|
||||||
|
|
||||||
|
% (cd ..; java scm.driver examples/exprcomp.jas; java results)
|
116
jasmin/jasmin-2.4/lib/jas/examples/exprcomp.jas
Normal file
116
jasmin/jasmin-2.4/lib/jas/examples/exprcomp.jas
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
;;; Simple arithmetic expression compiler for jas in jas.
|
||||||
|
;;;
|
||||||
|
;;; The compiler is defined in the function
|
||||||
|
;;; compile-expression
|
||||||
|
;;;
|
||||||
|
;;; use as (for instance)
|
||||||
|
;;; (compile-expression (quote (+ (* 2 (+ 1 3)) 1)))
|
||||||
|
;;;
|
||||||
|
;;; This will generate a standalone program called results.class
|
||||||
|
;;; Run the bytecode interpreter on it as:
|
||||||
|
;;;
|
||||||
|
;;; % java results
|
||||||
|
;;;
|
||||||
|
;;; which will print the result of the expression
|
||||||
|
|
||||||
|
(define compile-expression
|
||||||
|
(lambda (expr)
|
||||||
|
(real-compile-expression expr)
|
||||||
|
(dump-code)))
|
||||||
|
|
||||||
|
;; The fun part...
|
||||||
|
|
||||||
|
(define real-compile-expression
|
||||||
|
(lambda (expr)
|
||||||
|
(cond
|
||||||
|
|
||||||
|
((num? expr)
|
||||||
|
(compile-number expr))
|
||||||
|
|
||||||
|
(1 (progn
|
||||||
|
(real-compile-expression (get-op1 expr))
|
||||||
|
(real-compile-expression (get-op2 expr))
|
||||||
|
(compile-op (get-op expr))
|
||||||
|
(set! cur-stack-height (- cur-stack-height 1)))))))
|
||||||
|
|
||||||
|
;; Ah well. Back to boring bookkeeping.
|
||||||
|
|
||||||
|
|
||||||
|
(define compile-number
|
||||||
|
(lambda (num)
|
||||||
|
(append-insn (bipush num))
|
||||||
|
(set! cur-stack-height (+ 1 cur-stack-height))
|
||||||
|
(cond
|
||||||
|
((< max-stack-height cur-stack-height)
|
||||||
|
(set! max-stack-height cur-stack-height)))))
|
||||||
|
|
||||||
|
(define compile-op
|
||||||
|
(lambda (op)
|
||||||
|
(cond
|
||||||
|
((eq? op (quote +)) (append-insn (iadd)))
|
||||||
|
((eq? op (quote -)) (append-insn (isub)))
|
||||||
|
((eq? op (quote *)) (append-insn (imul)))
|
||||||
|
((eq? op (quote /)) (append-insn (idiv))))))
|
||||||
|
|
||||||
|
(define get-op1
|
||||||
|
(lambda (expr) (car (cdr expr))))
|
||||||
|
(define get-op2
|
||||||
|
(lambda (expr) (car (cdr (cdr expr)))))
|
||||||
|
(define get-op
|
||||||
|
(lambda (expr) (car expr)))
|
||||||
|
|
||||||
|
(define append-insn
|
||||||
|
(lambda (insn)
|
||||||
|
(jas-code-addinsn my-code insn)))
|
||||||
|
|
||||||
|
(define cur-stack-height 1)
|
||||||
|
(define max-stack-height 1)
|
||||||
|
|
||||||
|
(define my-code (make-code))
|
||||||
|
(define my-init-code (make-code))
|
||||||
|
|
||||||
|
; define the main() portion,
|
||||||
|
; and the call to print out the
|
||||||
|
; results.
|
||||||
|
(define append-sequence
|
||||||
|
(lambda (code-part insn-list)
|
||||||
|
(mapcar (lambda (insn) (jas-code-addinsn code-part insn))
|
||||||
|
insn-list)))
|
||||||
|
|
||||||
|
(append-sequence
|
||||||
|
my-init-code
|
||||||
|
(quote
|
||||||
|
((aload_0)
|
||||||
|
(invokenonvirtual (make-method-cpe "java/lang/Object" "<init>" "()V"))
|
||||||
|
(return))))
|
||||||
|
|
||||||
|
(define dump-code
|
||||||
|
(lambda ()
|
||||||
|
(define my-env (make-class-env))
|
||||||
|
(jas-class-setclass my-env (make-class-cpe "results"))
|
||||||
|
(jas-class-setsuperclass my-env (make-class-cpe "java/lang/Object"))
|
||||||
|
(jas-class-addmethod my-env acc-public "<init>" "()V" my-init-code ())
|
||||||
|
(append-sequence
|
||||||
|
my-code
|
||||||
|
(quote
|
||||||
|
((getstatic
|
||||||
|
(make-field-cpe "java/lang/System" "out" "Ljava/io/PrintStream;"))
|
||||||
|
(swap)
|
||||||
|
(invokevirtual (make-method-cpe
|
||||||
|
"java/io/PrintStream" "println" "(I)V"))
|
||||||
|
(return))))
|
||||||
|
(jas-code-stack-size my-code max-stack-height)
|
||||||
|
(jas-class-addmethod my-env
|
||||||
|
(| acc-public acc-static)
|
||||||
|
"main" "([Ljava/lang/String;)V" my-code ())
|
||||||
|
(jas-class-write my-env
|
||||||
|
(make-outputstream "results.class"))))
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; example usage of compiler.
|
||||||
|
;;;
|
||||||
|
;;; run the compiled class with
|
||||||
|
;;; % java results
|
||||||
|
;;; to get the answer.
|
||||||
|
|
||||||
|
(compile-expression (quote (+ (* 2 (+ 1 3)) 1)))
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue