Commit 46c20be8 authored by Samuel's avatar Samuel
Browse files

CA FONCTIONNE

parent 5e19810f
(** This is the same abstract syntax tree as in [LMJ.mli] but without position informations.
After typechecking, we don't need to give feedbacks to the user. *)
type identifier = string
type expression =
| EAdd of expression
| EConst of constant
| EGetVar of identifier
| EUnOp of unop * expression
| EBinOp of binop * expression * expression
| EMethodCall of expression * identifier * expression list
| EArrayGet of expression * expression
| EArrayAlloc of expression
| EArrayLength of expression
| EThis
| EObjectAlloc of identifier
and constant = LMJ.constant =
| ConstBool of bool
| ConstInt of int32
| ConstString of string
and binop = LMJ.binop =
| OpAdd
| OpSub
| OpMul
| OpLt
| OpGt
| OpEq
| OpAnd
and unop = LMJ.unop =
| UOpNot
| UOpAddPre
| UOpSubPre
| UOpAddPost
| UOpSubPost
and instruction =
| IExpr of expression
| IBlock of instruction list
| IIf of expression * instruction * instruction
| IWhile of expression * instruction
| IFor of identifier*expression*expression*identifier*expression*instruction
| ISyso of expression
| ISetVar of identifier * expression
| IArraySet of identifier * expression * expression
and typ =
| TypInt
| TypBool
| TypIntArray
| TypString
| Typ of identifier
and metho = {
formals: (identifier * typ) list;
result: typ;
locals: (identifier * typ) list;
body: instruction list;
return: expression
}
and clas = {
extends: identifier option;
attributes: (identifier * typ) list;
methods: (identifier * metho) list
}
and program = {
name: identifier;
defs: (identifier * clas) list;
main_args: identifier;
main: instruction list
}
......@@ -5,28 +5,25 @@
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/stringMap.ml": "\018\192gI^\203m\226/t\003OQ\185\192\165"
"Rule: ocaml dependencies mli (%=printTMJ )": "}\2193;\020.\224r\026rqJ\151\215tF"
"Rule: ocaml dependencies ml (%=error )": "\1398I\137\015\133\153\187^\1750vd\186[\193"
"Rule: ocaml: ml & cmi -> cmx & o (%=printMJ )": "]\170\204\028({\181G\140<\015\189\239\184\218\161"
"Rule: ocaml dependencies mli (%=MJ )": "\nc6.\160\031\255\167\153\214\219?\150\151\140\127"
"Rule: ocaml: ml & cmi -> cmx & o (%=lexer )": "\002\006\000&f\165\012n\158\231\133Y\179y\019\160"
"Rule: ocaml: ml & cmi -> cmx & o (%=mj2c )": "\239v\178\194\179E\018f\000\220\2260\208\027\029\210"
"Rule: ocaml: ml & cmi -> cmx & o (%=parser )": "\005\211\201,\200\164\160\130\180\028\228\163\243\151h\134"
"Rule: ocaml: ml & cmi -> cmx & o (%=mj2c )": "\190\207\245U\2430Y\141\193\"\156\236\235\223C\210"
"Rule: ocaml dependencies ml (%=print )": "\248+\222mS\162\248T\169#\002\167\b\170c\027"
"Rule: ocaml dependencies mli (%=print_ast )": "\028`h\240 }\148\184\253z\185\144'\153\1735"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/printMJ.ml": "\220 sa\233q\144\148k\138\230\199\019\232\235\138"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/stringSet.ml": "4\137\163zJL\210\133\158\207([+\019\240l"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/print_ast.ml": "\239\214\130'0\175\140q\166\176\2201\159\239\178\179"
"Rule: ocamllex (%=lexer )": "\248s\0279\026\128\204\244\234(,&\217/\228\159"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/print.mli": "h,\1908\169:\250*\165\201\213\217\183\127\243v"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/mj2c.ml": "\128\224B\r\0117\143\1752\167\204\2020\197\\,"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/mj2c.ml": "8\0221\230.\136\229t\018\007\183p\149\170\011\021"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/print_tokens.mli": "EWo\017\004\167\246b\195\165\233$\139\150P\131"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/parser.mly": "\206d\12865qfw\223@\197\159\242\018 /"
"Rule: ocaml: mli -> cmi (%=printTMJ )": "\166\001\203\182\184\181Lx\223\n\1270*\234\241z"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/main.ml": "\tZ\011,`\221\179\185O?\016\206\1508q\\"
"Rule: ocaml: mli -> cmi (%=printTMJ )": "\166\001\203\182\184\181Lx\223\n\1270*\234\241z"
"Rule: ocaml: mli -> cmi (%=typechecking )": "\130\162\140\129\196\177\248\154\181<([\181\137\188$"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/location.ml": "\240 \224_tD\166\029y\178\015%*\146AL"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/printTMJ.ml": "\215\191\185!Ps\255.\025\226\200\144\133_)\012"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/print_ast.mli": "\232OzMTO\155\136\199\230+\179\185vqy"
"Rule: ocaml: mli -> cmi (%=stringMap )": "A>\130\162\243\143G\174)\215\176\031\249=\162\001"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/printTMJ.ml": "\157*\255\1664\154kr2\167\224\028\220\206\229\231"
"Rule: ocaml: ml & cmi -> cmx & o (%=error )": "\251\249%C\249\247\180]r\129\143\225$.\191\031"
"Rule: ocaml: ml & cmi -> cmx & o (%=print )": "\240.\030\172\179\150\017\247\221\169\212\225\242\141\195\196"
"Rule: ocaml: ml & cmi -> cmx & o (%=print_ast )": "\165\027q\021i\170\148\150;E\t\225a\205[\026"
......@@ -34,34 +31,27 @@
"Rule: ocaml: ml & cmi -> cmx & o (%=stringMap )": "Y[\225\165k\030\157\130\196|\250\000\238\250O\215"
"Rule: ocaml dependencies ml (%=parser )": "\194\003{?\210L\022\160\rjA\225\157\196|\026"
"Rule: ocaml dependencies mli (%=stringMap )": "\230\220 \197\243Iv\232\199\140\163\029\022\189b\182"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/TMJ.mli": "\241\030G-\002K\219\026\157\139V\228Q\238~k"
"Rule: ocaml dependencies mli (%=LMJ )": "\243WT6\158\205\216W\012\158\200\188W/ \236"
"Rule: ocaml: mli -> cmi (%=MJ )": "\216\215`\025\014\2036=\177p\143k\1802e\208"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/TMJ.mli": "\241\030G-\002K\219\026\157\139V\228Q\238~k"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/lexer.mll": "\012\029\026\167,\224SZM\004\030n\150pEU"
"Rule: ocaml dependencies mli (%=print_tokens )": "\160\190G\n0\129\252\r\188\134 \229Q\174D\168"
"Rule: ocaml dependencies mli (%=error )": "\028^\151\178\231Z\235F\146sKm\201\234oj"
"Rule: ocaml: ml -> cmo & cmi (%=lexer )": "\175\0194HG\198\028$X\015\020X\251\018\142!"
"Rule: ocaml dependencies mli (%=printMJ )": "~(y\001\1866\149\245f\195m\240:\183t\161"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/lmj2mj.mli": "\199\236I\241\193U\007E\165\216k\159\t\203R\142"
"Rule: ocaml: mli -> cmi (%=location )": "\163\192(\147\226C+\223\133\141\193\1665g\199\189"
"Rule: ocaml: ml & cmi -> cmx & o (%=main )": "5Q\156\173\219)o\181Asnx/\222\172\173"
"Rule: ocaml: ml & cmi -> cmx & o (%=main )": "\\\191\140N\232\187\243`\179&\021\031\248IU\198"
"Rule: ocaml: mli -> cmi (%=mj2c )": "m4\016f0\185\182\184$\142g\127@\225\208\166"
"Rule: ocaml: ml -> cmo & cmi (%=main )": "k\242\172\163\224\184I\016\160\154\143\187\253\131\208l"
"Rule: ocaml dependencies ml (%=printMJ )": "+\166r\006\162\176\220\240\231\188s\195ax;\007"
"Rule: ocaml dependencies mli (%=print )": "%\021\1432&* \209\136W\144\136\214\241\231w"
"Rule: ocaml dependencies mli (%=parser )": "6.y\230\236\138\142\223k\005\248#\241\026V\132"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/print.ml": "u\238\204\1587\016\213\162\240W\247\230\228N\161\249"
"Rule: ocaml dependencies mli (%=TMJ )": "E\198\253\128\030gG4\153\172\234\254w+\184u"
"Rule: ocaml dependencies ml (%=print_tokens )": "\221(?\154\178M\210@\0245\134\145\147\177\172\134"
"Rule: ocaml dependencies mli (%=lmj2mj )": "\152WC\021E\168\b\140\223gV\150\172UP\231"
"Rule: ocaml dependencies mli (%=mj2c )": "\218,w|\005\195A\128\016\208\160.\179\241\146\174"
"Rule: ocaml dependencies ml (%=main )": "}\131\172\197f\007q\141n\191\183]\001\194\018\197"
"Rule: ocaml: mli -> cmi (%=print_ast )": "\176\002\026\218a\224\026\169\200\221\127\015\228\218\183."
"Rule: ocaml dependencies ml (%=lmj2mj )": "\248\155\134\140\"\168\\(vj\195\231\168\168\001#"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/print_tokens.ml": "\2275}\157.\186d}3\205\029)-0\195\227"
"Rule: ocaml: mli -> cmi (%=LMJ )": "\129w\025\003\rt\007}\021z=\216\184C\025\211"
"Rule: ocaml: ml & cmi -> cmx & o (%=typechecking )": "O\223\184Jr\t&\247h\250\002\254/^\184\183"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/MJ.mli": "Z|\n\131\181p\127PE\144\190\024\226\217\162\195"
"Rule: ocaml dependencies mli (%=typechecking )": "Z\241}>\030x\217\189@\021\217@K\129\244~"
"Rule: ocaml dependencies ml (%=print_ast )": "\204\133\155\159\255\230\153N\172\167O1\139=\014\130"
"Rule: ocaml dependencies mli (%=location )": "\b\000>Pd\149\169\213K\241\011q\207Z\142\201"
......@@ -72,24 +62,19 @@
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/typechecking.ml": "\184\182\183G\137\243\255\014\007Uo\140hZ8 "
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/error.mli": "g\143(]\222\176H\148\244<\149.}\028\143\246"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/mj2c.mli": "\130\029Y\249\169%\140\019\181\1407\212\133\145\193["
"Rule: ocaml dependencies ml (%=printTMJ )": "\188\207Bw\241\022\011TI\189]\165|i#\185"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/error.ml": "\163}\156,Nr\225\197\161\213!\244=\006\127Q"
"Rule: ocaml: mli -> cmi (%=print )": "]Z\176\017\134C\220\239\216\146Ee\"\020o\219"
"Rule: ocaml dependencies ml (%=printTMJ )": "B\249\171\152u\215\143\247\183\000\238[QAO\156"
"Rule: ocaml: ml & cmi -> cmx & o (%=location )": "\178\001\001Ca\133\024}\164\b\015\155\136dSi"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/stringMap.mli": "\226Y\t_\029\152\154\146\149/\162\250a\2516\004"
"Rule: ocaml: mli -> cmi (%=lmj2mj )": "`\031<e\143\214\253\231oX\254\251\157\207\018\218"
"Rule: ocaml: ml & cmi -> cmx & o (%=printTMJ )": "1\154\220<\015E\180\247A'L\bW\184\255="
"Rule: ocaml: ml & cmi -> cmx & o (%=printTMJ )": "Xj\244w\141I\177\229M\"\183\139.8\222\021"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/location.mli": "\196\247B\243\247\t\250\217\016w\021\021\238=\201\236"
"Rule: ocaml dependencies ml (%=mj2c )": "\148\197\015Dv\223NP\150e\224\237\233B\216M"
"Rule: ocaml: mli -> cmi (%=printMJ )": "I\155\014\015I\154\137&\157^.[d\184\160\000"
"Rule: ocaml dependencies ml (%=mj2c )": "S\134\255\220\001\153\175\149\022\t<\1844z\152\164"
"Rule: ocaml: mli -> cmi (%=parser )": "{\177\027\163b[1\225\160,\250H\226\200/\181"
"Rule: ocaml: ml & cmi -> cmx & o (%=print_tokens )": "\\O\213\n\179{\027\136Pc\017\201\181\148m`"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/lmj2mj.ml": "\187\254\128\011\210X\203\164\162\029\2090\026\179\149\t"
"Rule: ocaml dependencies mli (%=stringSet )": "TQ5\021\216\182\003\173\215\170V\252\167\203\142\197"
"Rule: ocaml: ml & cmi -> cmx & o (%=lmj2mj )": "\177V\147\177\174\206\228\199\246M\012\207\197\136\244\026"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/stringSet.mli": "\146\227\179\b\005zeI\210qcmv\244g\007"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/printMJ.mli": "M\000\t\218p\195\237\168\218\242\190\248\140\015\247\192"
"Rule: ocaml: cmx* & o* -> native (%=main )": "\012\219\197\215\199\250\181\007\179\1501\002\017\132ou"
"Rule: ocaml: cmx* & o* -> native (%=main )": "\207<\179\018\165\142\003\007}\238\141\202\000\\\220\244"
"Resource: /home/samuel/Bureau/ProjetCompil/MiniJava2/typechecking.mli": "VJ\190\130\177\133\1477\184\186\181\205\231\148\017\175"
"Rule: ocaml dependencies ml (%=location )": "\207\129\025K\236%\201u\152\150\233\n\210]\170\224"
"Rule: ocaml dependencies ml (%=stringMap )": "\197\201\019P\023\149\207\205H\165TR\164\012>\156"
......
......@@ -100,7 +100,9 @@ ocamldep.opt -modules printTMJ.ml > printTMJ.ml.depends # cached
# Target: printTMJ.cmx, tags: { compile, extension:cmx, extension:ml, file:printTMJ.cmx, file:printTMJ.ml, implem, native, ocaml, quiet }
ocamlopt.opt -c -I /usr/lib/ocaml -o printTMJ.cmx printTMJ.ml # cached
# Target: print_ast.ml.depends, tags: { extension:ml, file:print_ast.ml, ocaml, ocamldep, quiet }
ocamldep.opt -modules print_ast.ml > print_ast.ml.depends
ocamldep.opt -modules print_ast.ml > print_ast.ml.depends # cached
# Target: print_ast.cmx, tags: { compile, extension:cmx, extension:ml, file:print_ast.cmx, file:print_ast.ml, implem, native, ocaml, quiet }
ocamlopt.opt -c -I /usr/lib/ocaml -o print_ast.cmx print_ast.ml # cached
# Target: print_tokens.ml.depends, tags: { extension:ml, file:print_tokens.ml, ocaml, ocamldep, quiet }
ocamldep.opt -modules print_tokens.ml > print_tokens.ml.depends # cached
# Target: print_tokens.cmx, tags: { compile, extension:cmx, extension:ml, file:print_tokens.cmx, file:print_tokens.ml, implem, native, ocaml, quiet }
......@@ -109,45 +111,8 @@ ocamlopt.opt -c -I /usr/lib/ocaml -o print_tokens.cmx print_tokens.ml # cached
ocamldep.opt -modules typechecking.ml > typechecking.ml.depends # cached
# Target: typechecking.cmx, tags: { compile, extension:cmx, extension:ml, file:typechecking.cmx, file:typechecking.ml, implem, native, ocaml, quiet }
ocamlopt.opt -c -I /usr/lib/ocaml -o typechecking.cmx typechecking.ml # cached
# Target: print_ast.cmx, tags: { compile, extension:cmx, extension:ml, file:print_ast.cmx, file:print_ast.ml, implem, native, ocaml, quiet }
ocamlopt.opt -c -I /usr/lib/ocaml -o print_ast.cmx print_ast.ml
+ ocamlopt.opt -c -I /usr/lib/ocaml -o print_ast.cmx print_ast.ml
File "print_ast.ml", line 70, characters 21-69:
70 | .....................function
71 | | UOpNot ->
72 | fprintf out "UOpNot"
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(UOpAddPre|UOpSubPre|UOpAddPost|UOpSubPost)
File "print_ast.ml", line 179, characters 2-1191:
179 | ..match i with
180 | | ISyso e ->
181 | fprintf out "ISyso\n%s%s%a"
182 | prefix'
183 | branch_end
...
223 | (print_expression (prefix' ^ pipe)) e1
224 | prefix'
225 | branch_end
226 | (print_expression prefix') e2
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(IExpr _|IFor (_, _, _, _, _, _))
File "print_ast.ml", line 236, characters 2-192:
236 | ..match typ with
237 | | TypInt ->
238 | fprintf out "int"
239 | | TypBool ->
240 | fprintf out "bool"
241 | | TypIntArray ->
242 | fprintf out "int[]"
243 | | Typ id ->
244 | fprintf out "%a" print_identifier id
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
TypString
# Target: main.cmx, tags: { compile, extension:cmx, extension:ml, file:main.cmx, file:main.ml, implem, native, ocaml, quiet }
ocamlopt.opt -c -I /usr/lib/ocaml -o main.cmx main.ml
ocamlopt.opt -c -I /usr/lib/ocaml -o main.cmx main.ml # cached
# Target: main.native, tags: { dont_link_with, extension:native, file:main.native, link, native, ocaml, program, quiet }
ocamlopt.opt -I /usr/lib/ocaml /usr/lib/ocaml/unix.cmxa error.cmx location.cmx parser.cmx lexer.cmx print.cmx stringSet.cmx stringMap.cmx mj2c.cmx printTMJ.cmx print_ast.cmx print_tokens.cmx typechecking.cmx main.cmx -o main.native
ocamlopt.opt -I /usr/lib/ocaml /usr/lib/ocaml/unix.cmxa error.cmx location.cmx parser.cmx lexer.cmx print.cmx stringSet.cmx stringMap.cmx mj2c.cmx printTMJ.cmx print_ast.cmx print_tokens.cmx typechecking.cmx main.cmx -o main.native # cached
# Compilation successful.
(** We get rid of position informations. *)
let rec translate_expression e = translate_raw_expression (Location.content e)
and translate_raw_expression = function
| LMJ.EConst c -> MJ.EConst c
| LMJ.EGetVar id -> MJ.EGetVar (Location.content id)
| LMJ.EUnOp (op, e) -> MJ.EUnOp (op, translate_expression e)
| LMJ.EBinOp (op, e1, e2) -> MJ.EBinOp (op, translate_expression e1, translate_expression e2)
| LMJ.EMethodCall (o, id, args) -> MJ.EMethodCall (translate_expression o, Location.content id, List.map translate_expression args)
| LMJ.EArrayGet (a, i) -> MJ.EArrayGet (translate_expression a, translate_expression i)
| LMJ.EArrayAlloc e -> MJ.EArrayAlloc (translate_expression e)
| LMJ.EArrayLength e -> MJ.EArrayLength (translate_expression e)
| LMJ.EThis -> MJ.EThis
| LMJ.EObjectAlloc id -> MJ.EObjectAlloc (Location.content id)
and translate_instruction = function
LMJ.IBlock is -> MJ.IBlock (List.map translate_instruction is)
| LMJ.IIf (c, i1, i2) -> MJ.IIf (translate_expression c, translate_instruction i1, translate_instruction i2)
| LMJ.IWhile (c, i) -> MJ.IWhile (translate_expression c, translate_instruction i)
| LMJ.IFor (id, p, c, id2, p2, i) -> MJ.IFor (Location.content id, translate_expression p, translate_expression c,Location.content id2, translate_expression p2, translate_instruction i)
| LMJ.ISyso e -> MJ.ISyso (translate_expression e)
| LMJ.ISetVar (id, e) -> MJ.ISetVar (Location.content id, translate_expression e)
| LMJ.IArraySet (a, e1, e2) -> MJ.IArraySet (Location.content a, translate_expression e1, translate_expression e2)
let translate_typ = function
| LMJ.TypInt -> MJ.TypInt
| LMJ.TypBool -> MJ.TypBool
| LMJ.TypIntArray -> MJ.TypIntArray
| LMJ.Typ id -> MJ.Typ (Location.content id)
let translate_binding f (id, t) = (Location.content id, f t)
let translate_bindings f bindings =
List.map (translate_binding f) bindings
let translate_metho m =
{
MJ.formals = List.map (fun (id, t) -> (Location.content id, translate_typ t)) m.LMJ.formals;
MJ.result = translate_typ m.LMJ.result;
MJ.locals = translate_bindings translate_typ m.LMJ.locals;
MJ.body = List.map translate_instruction m.LMJ.body;
MJ.return = translate_expression m.LMJ.return
}
let translate_clas c =
{
MJ.extends =
(match c.LMJ.extends with
| None -> None
| Some id -> Some (Location.content id));
MJ.attributes = translate_bindings translate_typ c.LMJ.attributes;
MJ.methods = translate_bindings translate_metho c.LMJ.methods
}
let translate_program p =
{
MJ.name = Location.content p.LMJ.name;
MJ.defs = translate_bindings translate_clas p.LMJ.defs;
MJ.main = List.map translate_instruction p.LMJ.main;
MJ.main_args = Location.content p.LMJ.main_args
}
lmj2mj.ml: LMJ List Location MJ
(** Transforms an abstract syntax tree with position informations to an
abstract syntax tree without position informations. *)
(** [translate_program p] gets rid of position informations in [p]. *)
val translate_program : LMJ.program -> MJ.program
No preview for this file type
......@@ -356,13 +356,14 @@ let expr2c
: unit =
let rec expr2c out e =
match e.raw_expression with
EAdd e ->
fprintf out "%a++;"
expr2c e
|
|
EUnOp (UOpAddPre, e) ->
fprintf out "%a++"
expr2c e
|
EAdd e ->
fprintf out "%a++;"
expr2c e
| EUnOp (UOpAddPost, e) ->
fprintf out "++%a"
expr2c e
......
No preview for this file type
open Printf
open Print
open MJ
let indentation = 2
(** [constant out c] prints the constant [c] on the output channel [out]. *)
let constant out = function
| ConstBool true ->
fprintf out "true"
| ConstBool false ->
fprintf out "false"
| ConstInt i ->
fprintf out "%ld" i
| ConstString s ->
fprintf out "%s" s
(** [binop out op] prints the binary operator [op] on the output channel [out]. *)
let binop out = function
| OpAdd ->
fprintf out "+"
| OpSub ->
fprintf out "-"
| OpMul ->
fprintf out "*"
| OpLt ->
fprintf out "<"
| OpGt ->
fprintf out ">"
| OpEq ->
fprintf out "=="
| OpAnd ->
fprintf out "&&"
(** [expr out e], [expr0 out e], ..., [expr6 out e] print the expression [e]
on the output channel [out]. [expr] is a synonym for [expr6].
We have different functions to minimize the number of parenthesis. An expression
doesn't need parenthesis if the priority of its operands is greater or equal to
its priority.
[expr6] handles the expressions of least priority and [expr0] handles the expressions
of greatest priority. It's in the default case of [expr0] that we put parenthesis, in
this case, we have an expression of lower priority than the current context and so we
have to put parenthesis around it and then call [expr] again. *)
let rec expr0 out = function
| EConst c ->
fprintf out "%a" constant c
| EGetVar x ->
fprintf out "%s" x
| EThis ->
fprintf out "this"
| EMethodCall (o, c, es) ->
fprintf out "%a.%s(%a)"
expr0 o
c
(sep_list comma expr) es
| EArrayGet (ea, ei) ->
fprintf out "%a[%a]"
expr0 ea
expr ei
| EArrayLength e ->
fprintf out "%a.length"
expr0 e
| EObjectAlloc id ->
fprintf out "new %s()"
id
| e ->
fprintf out "(%a)"
expr e
and expr1 out = function
| EArrayAlloc e ->
fprintf out "new int[%a]"
expr e
| e ->
expr0 out e
and expr2 out = function
| EUnOp (UOpNot, e) ->
fprintf out "!%a"
expr2 e
| e ->
expr1 out e
and expr3 out = function
| EBinOp (OpMul as op, e1, e2) ->
fprintf out "%a %a %a"
expr3 e1
binop op
expr3 e2
| e ->
expr2 out e
and expr4 out = function
| EBinOp (OpSub as op, e1, e2) ->
fprintf out "%a %a %a"
expr4 e1
binop op
expr3 e2
| e ->
expr3 out e
and expr5 out = function
| EBinOp (OpAdd as op, e1, e2) ->
fprintf out "%a %a %a"
expr5 e1
binop op
expr5 e2
| e ->
expr4 out e
and expr6 out = function
| EBinOp ((OpLt | OpAnd | OpGt | OpEq) as op, e1, e2) ->
fprintf out "%a %a %a"
expr6 e1
binop op
expr6 e2
| e ->
expr5 out e
and expr out e =
expr6 out e
(** [binop out ins] prints the instruction [ins] on the output channel [out]. *)
let rec instr out = function
| IExpr(e) ->
fprintf out "%a;"
expr e
| ISetVar (x, e) ->
fprintf out "%s = %a;"
x
expr e
| IArraySet (id, ei, ev) ->
fprintf out "%s[%a] = %a;"
id
expr ei
expr ev
| IIf (c, i1, i2) ->
fprintf out "if (%a) %a%telse %a"
expr c
instr i1
nl
instr i2
| IWhile (c, i) ->
fprintf out "while (%a) %a"
expr c
instr i
| IFor(id, p, c, id2, p2, i) ->
fprintf out "for (%s = %a; %a; %s= %a) %a"
id
expr p
expr c
id2
expr p2
instr i
| IBlock is ->
fprintf out "{%a%t}"
(indent indentation (sep_list nl instr)) is
nl
| ISyso e ->
fprintf out "System.out.println(%a);"
expr e
(** [typ out t] prints the type [t] on the output channel [out]. *)
let typ out = function
TypString ->
fprintf out "String"
| TypInt ->
fprintf out "int"
| TypBool ->
fprintf out "boolean"
| TypIntArray ->
fprintf out "int[]"
| Typ id ->
fprintf out "%s"
id
(** [typ out (x, t)] prints the type [t] and the associated variable [x] on the output channel [out]. *)
let binding out (x, t) =
fprintf out "%a %s"
typ t
x
(** [metho out (name, m)] prints the method [name] with type [MJ.metho m] on the output channel [out]. *)
let metho out (name, m) =
fprintf out "public %a %s(%a) {%a%a%t%t}"
typ m.result
name
(sep_list comma binding) m.formals
(term_list semicolon (indent indentation binding)) m.locals
(list (indent indentation instr)) m.body
(indent_t indentation (fun out -> fprintf out "return %a;" expr m.return))
nl
(** [clas out (name, c)] prints the clas [name] with type [MJ.clas c] on the output channel [out]. *)
let clas out (name, c) =
(match c.extends with
| None ->
fprintf out "class %s {%a%a%t}" name
| Some class_name ->
fprintf out "class %s extends %s {%a%a%t}" name class_name)
(term_list semicolon (indent indentation binding)) c.attributes
(list (indent indentation metho)) c.methods
nl
let print_program out (p : MJ.program) : unit =
fprintf out "class %s {%t%t}%t%a"
p.name
(indent_t indentation
(fun out ->
fprintf out "public static void main(String[] %s) {%a%t}"
p.main_args
( list (indent indentation instr)) p.main
nl))
nl
nl
(sep_list nl clas) p.defs
printMJ.ml: MJ Print Printf
(** Transforms the abstract syntax tree of a MiniJava program back into a MiniJava source file. *)
(** [print_program out prog] transforms the abstract syntax tree [prog] back into Java and write the result on the [out] channel.
We can use this to check the result of parsing. We can use this too to indent a program. *)
val print_program : out_channel -> MJ.program -> unit
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment