first commit

This commit is contained in:
Jeena Paradies 2011-04-19 11:37:05 +02:00
commit 063194f8be
349 changed files with 36508 additions and 0 deletions

0
.j Normal file
View file

BIN
AbsJavalette.hi Normal file

Binary file not shown.

87
AbsJavalette.hs Normal file
View 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
View 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

Binary file not shown.

BIN
Compiler.hi Normal file

Binary file not shown.

195
Compiler.hs Normal file
View 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

Binary file not shown.

1
DocJavalette.aux Normal file
View file

@ -0,0 +1 @@
\relax

BIN
DocJavalette.dvi Normal file

Binary file not shown.

215
DocJavalette.log Normal file
View 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

File diff suppressed because it is too large Load diff

223
DocJavalette.tex Normal file
View 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
View 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
View 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
View 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

Binary file not shown.

26
ErrM.hs Normal file
View 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
View 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

Binary file not shown.

132
Javalette.cf Normal file
View 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

Binary file not shown.

36
Javalette.hs Normal file
View 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
View 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

Binary file not shown.

BIN
LexJavalette.hi Normal file

Binary file not shown.

340
LexJavalette.hs Normal file

File diff suppressed because one or more lines are too long

BIN
LexJavalette.o Normal file

Binary file not shown.

135
LexJavalette.x Normal file
View 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
View 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
View 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

Binary file not shown.

1214
ParJavalette.hs Normal file

File diff suppressed because it is too large Load diff

BIN
ParJavalette.o Normal file

Binary file not shown.

222
ParJavalette.y Normal file
View 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
View 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

Binary file not shown.

199
PrintJavalette.hs Normal file
View 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
View 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

Binary file not shown.

BIN
PrintUtils.class Normal file

Binary file not shown.

BIN
Runtime.class Normal file

Binary file not shown.

68
Runtime.java Normal file
View 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

Binary file not shown.

110
SkelJavalette.hs Normal file
View 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
View 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

Binary file not shown.

BIN
TestJavalette Executable file

Binary file not shown.

BIN
TestJavalette.hi Normal file

Binary file not shown.

58
TestJavalette.hs Normal file
View 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
View 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

Binary file not shown.

BIN
TypeChecker.hi Normal file

Binary file not shown.

321
TypeChecker.hs Normal file
View 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
View 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

Binary file not shown.

BIN
bnfc Executable file

Binary file not shown.

BIN
jasmin/jasmin-2.4.zip Normal file

Binary file not shown.

View 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
View 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
View 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
View 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 &#169; ${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 -->

View 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.

View 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 &lt;init&gt;()V
aload_0
invokenonvirtual java/lang/Object/&lt;init&gt;()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>

View 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 &lt;source-file&gt;
.class &lt;access-spec&gt; &lt;class-name&gt;
.super &lt;class-name&gt;
</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>&lt;class-name&gt;</dt>
<dd>is the full name of the class, including
any package names. For example foo/baz/MyClass.<p>
</dd>
<dt>&lt;access-spec&gt;</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 &lt;class-name&gt;
</pre>
<p>
where &lt;class-name&gt; 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 &lt;access-spec&gt; &lt;field-name&gt; &lt;descriptor&gt; [ = &lt;value&gt; ]
</pre>
<p>
where:</p>
<dl>
<dt>&lt;access-spec&gt;
<dd>is one of the keywords:
<dl><dd>
public, private, protected, static, final,
volatile, transient
</dl>
</dl><p>
<dt>&lt;field-name&gt;
<dd>is the name of the field.<p>
<dt>&lt;descriptor&gt;
<dd>is its type descriptor.<p>
<dt>&lt;value&gt;
<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 &lt;access-spec&gt; &lt;method-spec&gt;
&lt;statements&gt;
.end method
</pre>
<p>
where:</p>
<dl>
<dt>&lt;access-spec&gt;
<dd>is one of the keywords: public, private, protected, static, final,
synchronized, native, abstract<p>
<dt>&lt;method-spec&gt;
<dd>is the name and type descriptor of the method.<p>
<dt>&lt;statements&gt;
<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 &lt;integer&gt;</pre><p>
<dd>Sets the maximum size of the operand stack
required by the method.
<dt><pre>.limit locals &lt;integer&gt;</pre><p>
<dd>Sets the number of local variables
required by the method.
<dt><pre>.line &lt;integer&gt;</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 &lt;var-number&gt; is &lt;name&gt; &lt;descriptor&gt; from &lt;label1&gt; to &lt;label2&gt;</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 &lt;classname&gt;</pre><p>
<dd>Indicates that this method can throw
exceptions of the type indicated by &lt;classname&gt;.
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 &lt;classname&gt; from &lt;label1&gt; to &lt;label2&gt; using &lt;label3&gt;</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 &lt;classname&gt; or one of its subclasses is thrown
while executing the code between &lt;label1&gt; and &lt;label2&gt;, then
the runtime system should jump to &lt;label3&gt;. 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>

View 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>

View 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 &lt;var-num&gt;
aload &lt;var-num&gt;
astore &lt;var-num&gt;
dload &lt;var-num&gt;
dstore &lt;var-num&gt;
fload &lt;var-num&gt;
fstore &lt;var-num&gt;
iload &lt;var-num&gt;
istore &lt;var-num&gt;
lload &lt;var-num&gt;
lstore &lt;var-num&gt;
</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 &lt;int&gt;
sipush &lt;int&gt;
</pre>
for example:<p>
<pre>
bipush 100 ; push 100 onto the stack
</pre>
The iinc instruction takes two integer parameters:<p>
<pre>
iinc &lt;var-num&gt; &lt;amount&gt;
</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 &lt;label&gt;
goto_w &lt;label&gt;
if_acmpeq &lt;label&gt;
if_acmpne &lt;label&gt;
if_icmpeq &lt;label&gt;
if_icmpge &lt;label&gt;
if_icmpgt &lt;label&gt;
if_icmple &lt;label&gt;
if_icmplt &lt;label&gt;
if_icmpne &lt;label&gt;
ifeq &lt;label&gt;
ifge &lt;label&gt;
ifgt &lt;label&gt;
ifle &lt;label&gt;
iflt &lt;label&gt;
ifne &lt;label&gt;
ifnonnull &lt;label&gt;
ifnull &lt;label&gt;
jsr &lt;label&gt;
jsr_w &lt;label&gt;
</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 &lt;class&gt;
checkcast &lt;class&gt;
instanceof &lt;class&gt;
new &lt;class&gt;
</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 &lt;method-spec&gt;
invokestatic &lt;method-spec&gt;
invokevirtual &lt;method-spec&gt;
</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 &lt;method-spec&gt; and
an integer indicating how many arguments the method takes:<p>
<pre>
invokeinterface &lt;method-spec&gt; &lt;num-args&gt;
</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 &lt;field-spec&gt; &lt;descriptor&gt;
getstatic &lt;field-spec&gt; &lt;descriptor&gt;
putfield &lt;field-spec&gt; &lt;descriptor&gt;
putstatic &lt;field-spec&gt; &lt;descriptor&gt;
</pre>
for example:
<pre>
; get java.lang.System.out, which is a PrintStream
getstatic java/lang/System/out Ljava/io/PrintStream;
</pre>
&lt;field-spec&gt; is composed of two parts, a classname and a fieldname. The
classname is all of the characters in the &lt;field-spec&gt; 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>
&lt;descriptor&gt; 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 &lt;array-type&gt;
</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 &lt;array-descriptor&gt; &lt;num-dimensions&gt;
</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 &lt;constant&gt;
ldc_w &lt;constant&gt;
</pre>
&lt;constant&gt; 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>
&lt;lookupswitch&gt; ::=
lookupswitch
&lt;int1&gt; : &lt;label1&gt;
&lt;int2&gt; : &lt;label2&gt;
...
default : &lt;default-label&gt;
</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>
&lt;tableswitch&gt; ::=
tableswitch &lt;low&gt;
&lt;label1&gt;
&lt;label2&gt;
...
default : &lt;default-label&gt;
</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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View 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;}

View 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'

View 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

View 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

View 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

View 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

View 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

View 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

View file

@ -0,0 +1,5 @@
This shows how to run HelloApplet:<p>
<applet code="HelloWeb.class" width=350 height=75>
</applet>

View 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

Binary file not shown.

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View 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;}

View 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>
&lt;jas_file&gt; {
&lt;jasmin_header&gt;
[&lt;field&gt;]*
[&lt;method&gt;]*
}
</pre>
<h1>JasminXT Header</h1>
<pre>
&lt;jasmin_header&gt; {
[.bytecode &lt;x.y&gt;]
[.source &lt;sourcefile&gt;]
&lt;class_spec&gt;
&lt;super_spec&gt;
&lt;implements&gt;
[.signature "&lt;signature&gt;"]
[.enclosing method &lt;method_name&gt;]
[.debug "&lt;debug_source_extension&gt;"]*
[.inner class [&lt;access&gt;] [&lt;name&gt;] [inner &lt;classname&gt;] [outer &lt;name&gt;]]*
[.inner interface [&lt;access&gt;] [&lt;name&gt;] [inner &lt;classname&gt;] [outer &lt;name&gt;]]*
}
example :
.bytecode 49.0
.source hello.j
.class hello
.super java/lang/Object
.signature "&lt;my::own&gt;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>
&lt;class_spec&gt; {
.class &lt;access_spec&gt; &lt;class_name&gt;
}
</pre>
<p>where &lt;access_spec&gt; 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 &lt;class_name&gt; is the fully qualified internal form of the class, such as
my/package/MyClass</p><br>
<pre>
&lt;super_spec&gt; {
.super &lt;class_name&gt;
}
</pre>
<pre>
&lt;implements&gt; {
.implements &lt;class_name&gt;*
}
</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>
&lt;field&gt; {
.field &lt;access_spec&gt; &lt;field_name&gt; &lt;descriptor&gt; [signature &lt;signature&gt;]
[ = &lt;value&gt; ]
|
.field &lt;access_spec&gt; &lt;field_name&gt; &lt;descriptor&gt; [signature &lt;signature&gt;]
[ = &lt;value&gt; ]
[&lt;field_attribute&gt;]*
.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>
&lt;field_attribute&gt; {
.deprecated
| .attribute &lt;name&gt; &lt;file_name&gt;
| .signature &lt;signature&gt;
| .annotation (...)
}
</pre>
(see below for the definition of the annotation and the attribute directives)
<p>examples :
<pre>.field enum myField Ljava/lang/String; signature "&lt;my::own&gt;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>
&lt;method&gt; {
.method &lt;access_spec&gt; &lt;method_name&gt; &lt;descriptor&gt;
&lt;statement&gt;*
.end method
}
</pre>
<h1>JasminXT Method Statements</h1>
<pre>
&lt;statement&gt; {
.limit stack &lt;integer&gt;
| .limit locals &lt;integer&gt;
| .line &lt;integer&gt;
| .var &lt;var_number&gt; is &lt;var_name&gt; &lt;descriptor&gt; [signature &lt;sign&gt;] from &lt;label1&gt; to &lt;label2&gt;
| .var &lt;var_number&gt; is &lt;var_name&gt; &lt;descriptor&gt; [signature &lt;sign&gt;] from &lt;offset1&gt; to &lt;offset2&gt;
| .throws &lt;classname&gt;
| .catch &lt;classname&gt; from &lt;label1&gt; to &lt;label2&gt; using &lt;label3&gt;
| .catch &lt;classname&gt; from &lt;offset1&gt; to &lt;offset2&gt; using &lt;offset3&gt;
| .signature "&lt;signature&gt;"
| .stack
[offset {&lt;pc&gt; | &lt;label&gt;}]
[locals &lt;verification_type&gt; [&lt;verification_arg&gt;]]
(...)
[stack &lt;verification_type&gt; [&lt;verification_arg&gt;]]
(...)
.end stack
| .stack use [n] locals
(...)
.end stack
| &lt;instruction&gt; [&lt;instruction_args&gt;]
| &lt;Label&gt;:
| .deprecated
| &lt;generic&gt; ; 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. &lt;pc&gt; is an offset in the local bytecode array.
&lt;verification_type&gt; is one of the following keywords : Top, Integer,
Float, Long, Double, Null, UninitializedThis, Object or Uninitialized. Object
takes a &lt;classname&gt; 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 &lt;n&gt; values from
previous .stack directive. If &lt;n&gt; 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>
&lt;instruction&gt; {
[&lt;pc&gt;:] &lt;opcode&gt; [&lt;instruction_args&gt;]
}
</pre>
<p>
The main change in JasminXT is that it is now possible to put the offset of the
instruction before the opcode (the &lt;pc&gt;: 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>&lt;generic&gt; = {
.attribute &lt;name&gt; &lt;file_name&gt;
}</pre>
&lt;name&gt; is the name of the attribute and &lt;file_name&gt; 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>
&lt;annotation&gt; = {
.annotation visible &lt;classname&gt;
| .annotation invisible &lt;classname>&gt;
| .annotation visibleparam &lt;paramnum&gt; &lt;classname&gt;
| .annotation invisibleparam &lt;paramnum&gt; &lt;classname&gt;
| .annotation default
........
.end annotation
Field format (except AnnotationDefault):
&lt;name&gt; &lt;signchar&gt; = &lt;value&gt;*
| &lt;name&gt; @ = .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>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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.

View 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

View 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)

View 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