diff --git a/.cm/SKEL/main.sml b/.cm/SKEL/main.sml index 0c6d7e2..574ac93 100644 --- a/.cm/SKEL/main.sml +++ b/.cm/SKEL/main.sml @@ -1,2 +1,3 @@ Skeleton 5 -d2f4d"Parse"d"Symbol"d"TextIO"d"Printtree"ad"Main"h3aä¢F"gp1d"MIPSFrame"aä¢R"jgp1’5gp1e"Translate"ad"S"jgp1’ gp1e"Semant" \ No newline at end of file +d2f7d"List"d"Temp"Cd"Assem"d"Canon"d"Parse"d"TextIO"d"MIPSGen"Nad"Main"h3aä¢F"gp1d"MIPSFrame"aä¢Tr"jgp1’ +gp1e"Translate"ad"S"jgp1’gp1e"Semant" \ No newline at end of file diff --git a/.cm/amd64-unix/main.sml b/.cm/amd64-unix/main.sml index 1cad9ab..cf55aad 100644 Binary files a/.cm/amd64-unix/main.sml and b/.cm/amd64-unix/main.sml differ diff --git a/IR/.cm/amd64-unix/temp.sig b/IR/.cm/amd64-unix/temp.sig index 0b84e1b..5c98f83 100644 Binary files a/IR/.cm/amd64-unix/temp.sig and b/IR/.cm/amd64-unix/temp.sig differ diff --git a/IR/.cm/amd64-unix/temp.sml b/IR/.cm/amd64-unix/temp.sml index f53e769..2ed6df6 100644 Binary files a/IR/.cm/amd64-unix/temp.sml and b/IR/.cm/amd64-unix/temp.sml differ diff --git a/IR/.cm/amd64-unix/translate.sig b/IR/.cm/amd64-unix/translate.sig index efd5eb1..f388b86 100644 Binary files a/IR/.cm/amd64-unix/translate.sig and b/IR/.cm/amd64-unix/translate.sig differ diff --git a/IR/.cm/amd64-unix/translate.sml b/IR/.cm/amd64-unix/translate.sml index 0ee8a44..e118514 100644 Binary files a/IR/.cm/amd64-unix/translate.sml and b/IR/.cm/amd64-unix/translate.sml differ diff --git a/absyn/.cm/amd64-unix/absyn.sml b/absyn/.cm/amd64-unix/absyn.sml index f64f016..bdf3e12 100644 Binary files a/absyn/.cm/amd64-unix/absyn.sml and b/absyn/.cm/amd64-unix/absyn.sml differ diff --git a/absyn/.cm/amd64-unix/prabsyn.sml b/absyn/.cm/amd64-unix/prabsyn.sml index 7bbf170..f9de44e 100644 Binary files a/absyn/.cm/amd64-unix/prabsyn.sml and b/absyn/.cm/amd64-unix/prabsyn.sml differ diff --git a/absyn/.cm/amd64-unix/types.sml b/absyn/.cm/amd64-unix/types.sml index 1477050..b4fd6c4 100644 Binary files a/absyn/.cm/amd64-unix/types.sml and b/absyn/.cm/amd64-unix/types.sml differ diff --git a/assem/.cm/GUID/assem.sml b/assem/.cm/GUID/assem.sml new file mode 100644 index 0000000..24ed6e9 --- /dev/null +++ b/assem/.cm/GUID/assem.sml @@ -0,0 +1 @@ +guid-(sources.cm):assem/assem.sml-1586561322.670 diff --git a/assem/.cm/GUID/canon.sml b/assem/.cm/GUID/canon.sml new file mode 100644 index 0000000..6912506 --- /dev/null +++ b/assem/.cm/GUID/canon.sml @@ -0,0 +1 @@ +guid-(sources.cm):assem/canon.sml-1586561087.582 diff --git a/assem/.cm/GUID/codegen.sig b/assem/.cm/GUID/codegen.sig new file mode 100644 index 0000000..2073b87 --- /dev/null +++ b/assem/.cm/GUID/codegen.sig @@ -0,0 +1 @@ +guid-(sources.cm):assm/codegen.sig-1586560191.741 diff --git a/frame/.cm/GUID/frame.sig b/assem/.cm/GUID/frame.sig similarity index 100% rename from frame/.cm/GUID/frame.sig rename to assem/.cm/GUID/frame.sig diff --git a/frame/.cm/GUID/mipsframe.sml b/assem/.cm/GUID/mipsframe.sml similarity index 100% rename from frame/.cm/GUID/mipsframe.sml rename to assem/.cm/GUID/mipsframe.sml diff --git a/assem/.cm/SKEL/assem.sml b/assem/.cm/SKEL/assem.sml new file mode 100644 index 0000000..2544b11 --- /dev/null +++ b/assem/.cm/SKEL/assem.sml @@ -0,0 +1,2 @@ +Skeleton 5 +d2f4d"List"d"Temp"d"Symbol"d"ErrorMsg"ad"Assem"h0 \ No newline at end of file diff --git a/assem/.cm/SKEL/canon.sml b/assem/.cm/SKEL/canon.sml new file mode 100644 index 0000000..5b3f103 --- /dev/null +++ b/assem/.cm/SKEL/canon.sml @@ -0,0 +1,2 @@ +Skeleton 5 +d3f3d"Temp"ä¢Tree"d"Symbol"ać¢CANON"h0ad"Canon"jh1ad"T"gp1’ gp1’ \ No newline at end of file diff --git a/assem/.cm/SKEL/codegen.sig b/assem/.cm/SKEL/codegen.sig new file mode 100644 index 0000000..27710c4 --- /dev/null +++ b/assem/.cm/SKEL/codegen.sig @@ -0,0 +1,2 @@ +Skeleton 5 +d2f2d"Tree"d"Assem"ac"CODEGEN"h1ad"Frame"gp1c"FRAME" \ No newline at end of file diff --git a/frame/.cm/SKEL/frame.sig b/assem/.cm/SKEL/frame.sig similarity index 100% rename from frame/.cm/SKEL/frame.sig rename to assem/.cm/SKEL/frame.sig diff --git a/frame/.cm/SKEL/mipsframe.sml b/assem/.cm/SKEL/mipsframe.sml similarity index 100% rename from frame/.cm/SKEL/mipsframe.sml rename to assem/.cm/SKEL/mipsframe.sml diff --git a/assem/.cm/amd64-unix/assem.sml b/assem/.cm/amd64-unix/assem.sml new file mode 100644 index 0000000..d34c848 Binary files /dev/null and b/assem/.cm/amd64-unix/assem.sml differ diff --git a/assem/.cm/amd64-unix/canon.sml b/assem/.cm/amd64-unix/canon.sml new file mode 100644 index 0000000..425100f Binary files /dev/null and b/assem/.cm/amd64-unix/canon.sml differ diff --git a/assem/.cm/amd64-unix/codegen.sig b/assem/.cm/amd64-unix/codegen.sig new file mode 100644 index 0000000..fd602ef Binary files /dev/null and b/assem/.cm/amd64-unix/codegen.sig differ diff --git a/assem/.cm/amd64-unix/frame.sig b/assem/.cm/amd64-unix/frame.sig new file mode 100644 index 0000000..ebf2a55 Binary files /dev/null and b/assem/.cm/amd64-unix/frame.sig differ diff --git a/frame/.cm/amd64-unix/mipsframe.sml b/assem/.cm/amd64-unix/mipsframe.sml similarity index 100% rename from frame/.cm/amd64-unix/mipsframe.sml rename to assem/.cm/amd64-unix/mipsframe.sml diff --git a/assem/assem.sml b/assem/assem.sml new file mode 100644 index 0000000..cb89524 --- /dev/null +++ b/assem/assem.sml @@ -0,0 +1,39 @@ +structure Assem = struct + + type reg = string + type temp = Temp.temp + type label = Temp.label + + datatype instr = OPER of {assem: string, + dst: temp list, + src: temp list, + jump: label list option} + | LABEL of {assem: string, lab: Temp.label} + | MOVE of {assem: string, + dst: temp, + src: temp} + + fun format saytemp = + let + fun speak(assem,dst,src,jump) = + let val saylab = Symbol.name + fun f(#"`":: #"s":: i::rest) = + (explode(saytemp(List.nth(src,ord i - ord #"0"))) @ f rest) + | f( #"`":: #"d":: i:: rest) = + (explode(saytemp(List.nth(dst,ord i - ord #"0"))) @ f rest) + | f( #"`":: #"j":: i:: rest) = + (explode(saylab(List.nth(jump,ord i - ord #"0"))) @ f rest) + | f( #"`":: #"`":: rest) = #"`" :: f rest + | f( #"`":: _ :: rest) = ErrorMsg.impossible "bad Assem format" + | f(c :: rest) = (c :: f rest) + | f nil = nil + in implode(f(explode assem)) + end + in fn OPER{assem,dst,src,jump=NONE} => speak(assem,dst,src,nil) + | OPER{assem,dst,src,jump=SOME j} => speak(assem,dst,src,j) + | LABEL{assem,...} => assem + | MOVE{assem,dst,src} => speak(assem,[dst],[src],nil) + end + +end + diff --git a/assem/canon.sml b/assem/canon.sml new file mode 100644 index 0000000..7e0ea9c --- /dev/null +++ b/assem/canon.sml @@ -0,0 +1,183 @@ +signature CANON = +sig + val linearize : Tree.stm -> Tree.stm list + (* From an arbitrary Tree statement, produce a list of cleaned trees + satisfying the following properties: + 1. No SEQ's or ESEQ's + 2. The parent of every CALL is an EXP(..) or a MOVE(TEMP t,..) + *) + + val basicBlocks : Tree.stm list -> (Tree.stm list list * Tree.label) + (* From a list of cleaned trees, produce a list of + basic blocks satisfying the following properties: + 1. and 2. as above; + 3. Every block begins with a LABEL; + 4. A LABEL appears only at the beginning of a block; + 5. Any JUMP or CJUMP is the last stm in a block; + 6. Every block ends with a JUMP or CJUMP; + Also produce the "label" to which control will be passed + upon exit. + *) + + val traceSchedule : Tree.stm list list * Tree.label -> Tree.stm list + (* From a list of basic blocks satisfying properties 1-6, + along with an "exit" label, + produce a list of stms such that: + 1. and 2. as above; + 7. Every CJUMP(_,t,f) is immediately followed by LABEL f. + The blocks are reordered to satisfy property 7; also + in this reordering as many JUMP(T.NAME(lab)) statements + as possible are eliminated by falling through into T.LABEL(lab). + *) +end + +structure Canon : CANON = +struct + + structure T = Tree + + fun linearize(stm0: T.stm) : T.stm list = + let + infix % + fun (T.EXP(T.CONST _)) % x = x + | x % (T.EXP(T.CONST _)) = x + | x % y = T.SEQ(x,y) + + fun commute(T.EXP(T.CONST _), _) = true + | commute(_, T.NAME _) = true + | commute(_, T.CONST _) = true + | commute _ = false + + val nop = T.EXP(T.CONST 0) + + fun reorder ((e as T.CALL _ )::rest) = + let val t = Temp.newtemp() + in reorder(T.ESEQ(T.MOVE(T.TEMP t, e), T.TEMP t) :: rest) + end + | reorder (a::rest) = + let val (stms,e) = do_exp a + val (stms',el) = reorder rest + in if commute(stms',e) + then (stms % stms',e::el) + else let val t = Temp.newtemp() + in (stms % T.MOVE(T.TEMP t, e) % stms', T.TEMP t :: el) + end + end + | reorder nil = (nop,nil) + + and reorder_exp(el,build) = let val (stms,el') = reorder el + in (stms, build el') + end + + and reorder_stm(el,build) = let val (stms,el') = reorder (el) + in stms % build(el') + end + + and do_stm(T.SEQ(a,b)) = + do_stm a % do_stm b + | do_stm(T.JUMP(e,labs)) = + reorder_stm([e],fn [e] => T.JUMP(e,labs)) + | do_stm(T.CJUMP(p,a,b,t,f)) = + reorder_stm([a,b], fn[a,b]=> T.CJUMP(p,a,b,t,f)) + | do_stm(T.MOVE(T.TEMP t,T.CALL(e,el))) = + reorder_stm(e::el,fn e::el => T.MOVE(T.TEMP t,T.CALL(e,el))) + | do_stm(T.MOVE(T.TEMP t,b)) = + reorder_stm([b],fn[b]=>T.MOVE(T.TEMP t,b)) + | do_stm(T.MOVE(T.MEM e,b)) = + reorder_stm([e,b],fn[e,b]=>T.MOVE(T.MEM e,b)) + | do_stm(T.MOVE(T.ESEQ(s,e),b)) = + do_stm(T.SEQ(s,T.MOVE(e,b))) + | do_stm(T.EXP(T.CALL(e,el))) = + reorder_stm(e::el,fn e::el => T.EXP(T.CALL(e,el))) + | do_stm(T.EXP e) = + reorder_stm([e],fn[e]=>T.EXP e) + | do_stm s = reorder_stm([],fn[]=>s) + + and do_exp(T.BINOP(p,a,b)) = + reorder_exp([a,b], fn[a,b]=>T.BINOP(p,a,b)) + | do_exp(T.MEM(a)) = + reorder_exp([a], fn[a]=>T.MEM(a)) + | do_exp(T.ESEQ(s,e)) = + let val stms = do_stm s + val (stms',e) = do_exp e + in (stms%stms',e) + end + | do_exp(T.CALL(e,el)) = + reorder_exp(e::el, fn e::el => T.CALL(e,el)) + | do_exp e = reorder_exp([],fn[]=>e) + + (* linear gets rid of the top-level SEQ's, producing a list *) + fun linear(T.SEQ(a,b),l) = linear(a,linear(b,l)) + | linear(s,l) = s::l + + in (* body of linearize *) + linear(do_stm stm0, nil) + end + + type block = T.stm list + + (* Take list of statements and make basic blocks satisfying conditions + 3 and 4 above, in addition to the extra condition that + every block ends with a JUMP or CJUMP *) + + fun basicBlocks stms = + let val done = Temp.newlabel() + fun blocks((head as T.LABEL _) :: tail, blist) = + let fun next((s as (T.JUMP _))::rest, thisblock) = + endblock(rest, s::thisblock) + | next((s as (T.CJUMP _))::rest, thisblock) = + endblock(rest,s::thisblock) + | next(stms as (T.LABEL lab :: _), thisblock) = + next(T.JUMP(T.NAME lab,[lab]) :: stms, thisblock) + | next(s::rest, thisblock) = next(rest, s::thisblock) + | next(nil, thisblock) = + next([T.JUMP(T.NAME done, [done])], thisblock) + + and endblock(stms, thisblock) = + blocks(stms, rev thisblock :: blist) + + in next(tail, [head]) + end + | blocks(nil, blist) = rev blist + | blocks(stms, blist) = blocks(T.LABEL(Temp.newlabel())::stms, blist) + in (blocks(stms,nil), done) + end + + fun enterblock(b as (T.LABEL s :: _), table) = Symbol.enter(table,s,b) + | enterblock(_, table) = table + + fun splitlast([x]) = (nil,x) + | splitlast(h::t) = let val (t',last) = splitlast t in (h::t', last) end + + fun trace(table,b as (T.LABEL lab :: _),rest) = + let val table = Symbol.enter(table, lab, nil) + in case splitlast b + of (most,T.JUMP(T.NAME lab, _)) => + (case Symbol.look(table, lab) + of SOME(b' as _::_) => most @ trace(table, b', rest) + | _ => b @ getnext(table,rest)) + | (most,T.CJUMP(opr,x,y,t,f)) => + (case (Symbol.look(table,t), Symbol.look(table,f)) + of (_, SOME(b' as _::_)) => b @ trace(table, b', rest) + | (SOME(b' as _::_), _) => + most @ [T.CJUMP(T.notRel opr,x,y,f,t)] + @ trace(table, b', rest) + | _ => let val f' = Temp.newlabel() + in most @ [T.CJUMP(opr,x,y,t,f'), + T.LABEL f', T.JUMP(T.NAME f,[f])] + @ getnext(table,rest) + end) + | (most, T.JUMP _) => b @ getnext(table,rest) + end + + and getnext(table,(b as (T.LABEL lab::_))::rest) = + (case Symbol.look(table, lab) + of SOME(_::_) => trace(table,b,rest) + | _ => getnext(table,rest)) + | getnext(table,nil) = nil + + fun traceSchedule(blocks,done) = + getnext(foldr enterblock Symbol.empty blocks, blocks) + @ [T.LABEL done] + +end diff --git a/assem/codegen.sig b/assem/codegen.sig new file mode 100644 index 0000000..e42f109 --- /dev/null +++ b/assem/codegen.sig @@ -0,0 +1,5 @@ +signature CODEGEN = +sig + structure Frame : FRAME + val codeGen : Frame.frame -> Tree.stm -> Assem.instr list +end \ No newline at end of file diff --git a/frame/frame.sig b/assem/frame.sig similarity index 87% rename from frame/frame.sig rename to assem/frame.sig index 067b89e..20e1687 100644 --- a/frame/frame.sig +++ b/assem/frame.sig @@ -12,9 +12,10 @@ sig val wordSize : int val exp : access * Tree.exp -> Tree.exp - val name : frame -> Temp.label + val name : frame -> string val formals : frame -> access list val nextFrame : {name: Temp.label, formals: bool list} -> frame + val string: Temp.label * string -> string val allocateLocal : frame -> bool -> access diff --git a/assem/graph/flowgraph.sml b/assem/graph/flowgraph.sml new file mode 100644 index 0000000..f427102 --- /dev/null +++ b/assem/graph/flowgraph.sml @@ -0,0 +1,23 @@ +structure Flow = +struct + datatype flowgraph = FGRAPH of {control: Graph.graph, + def: Temp.temp list Graph.Table.table, + use: Temp.temp list Graph.Table.table, + ismove: bool Graph.Table.table} + + (* Note: any "use" within the block is assumed to be BEFORE a "def" + of the same variable. If there is a def(x) followed by use(x) + in the same block, do not mention the use in this data structure, + mention only the def. + + More generally: + If there are any nonzero number of defs, mention def(x). + If there are any nonzero number of uses BEFORE THE FIRST DEF, + mention use(x). + + For any node in the graph, + Graph.Table.look(def,node) = SOME(def-list) + Graph.Table.look(use,node) = SOME(use-list) + *) + +end diff --git a/assem/graph/graph.sig b/assem/graph/graph.sig new file mode 100644 index 0000000..51db896 --- /dev/null +++ b/assem/graph/graph.sig @@ -0,0 +1,23 @@ +signature GRAPH = +sig + type graph + type node + + val nodes: graph -> node list + val succ: node -> node list + val pred: node -> node list + val adj: node -> node list (* succ+pred *) + val eq: node*node -> bool + + val newGraph: unit -> graph + val newNode : graph -> node + exception GraphEdge + val mk_edge: {from: node, to: node} -> unit + val rm_edge: {from: node, to: node} -> unit + + structure Table : TABLE + sharing type Table.key = node + + val nodename: node->string (* for debugging only *) + +end diff --git a/assem/graph/graph.sml b/assem/graph/graph.sml new file mode 100644 index 0000000..a2b6d5c --- /dev/null +++ b/assem/graph/graph.sml @@ -0,0 +1,80 @@ +structure Graph :> GRAPH = +struct + type node' = int + type temp = Temp.temp + + datatype noderep = NODE of {succ: node' list, pred: node' list} + + val emptyNode = NODE{succ=[],pred=[]} + + val bogusNode = NODE{succ=[~1],pred=[]} + + fun isBogus(NODE{succ= ~1::_,...}) = true + | isBogus _ = false + + structure A = DynamicArrayFn(struct open Array + type elem = noderep + type vector = noderep vector + type array = noderep array + end) + + type graph = A.array + + type node = graph * node' + fun eq((_,a),(_,b)) = a=b + + fun augment (g: graph) (n: node') : node = (g,n) + + fun newGraph() = A.array(0,bogusNode) + + fun nodes g = let val b = A.bound g + fun f i = if isBogus( A.sub(g,i)) then nil + else (g,i)::f(i+1) + in f 0 + end + + fun succ(g,i) = let val NODE{succ=s,...} = A.sub(g,i) + in map (augment g) s + end + fun pred(g,i) = let val NODE{pred=p,...} = A.sub(g,i) + in map (augment g) p + end + fun adj gi = pred gi @ succ gi + + fun newNode g = (* binary search for unused node *) + let fun look(lo,hi) = + (* i < lo indicates i in use + i >= hi indicates i not in use *) + if lo=hi then (A.update(g,lo,emptyNode); (g,lo)) + else let val m = (lo+hi) div 2 + in if isBogus(A.sub(g,m)) then look(lo,m) else look(m+1,hi) + end + in look(0, 1 + A.bound g) + end + + exception GraphEdge + fun check(g,g') = (* if g=g' then () else raise GraphEdge *) () + + fun delete(i,j::rest) = if i=j then rest else j::delete(i,rest) + | delete(_,nil) = raise GraphEdge + + fun diddle_edge change {from=(g:graph, i),to=(g':graph, j)} = + let val _ = check(g,g') + val NODE{succ=si,pred=pi} = A.sub(g,i) + val _ = A.update(g,i,NODE{succ=change(j,si),pred=pi}) + val NODE{succ=sj,pred=pj} = A.sub(g,j) + val _ = A.update(g,j,NODE{succ=sj,pred=change(i,pj)}) + in () + end + + val mk_edge = diddle_edge (op ::) + val rm_edge = diddle_edge delete + + structure Table = IntMapTable(type key = node + fun getInt(g,n) = n) + + + fun nodename(g,i:int) = "n" ^ Int.toString(i) + +end + diff --git a/frame/.cm/amd64-unix/frame.sig b/frame/.cm/amd64-unix/frame.sig deleted file mode 100644 index 29a0fc8..0000000 Binary files a/frame/.cm/amd64-unix/frame.sig and /dev/null differ diff --git a/main.sml b/main.sml index 3166cf9..015d272 100644 --- a/main.sml +++ b/main.sml @@ -1,29 +1,37 @@ -structure Main = +structure Main = struct + structure F = MIPSFrame - structure R = Translate (F) - structure S = Semant (R) + structure Tr = Translate(F) + structure S = Semant(Tr) + (* structure R = RegAlloc *) - fun main (fileName : string) = - let val _ = () - - (* Lex and Parse --> AST *) - val absyn = Parse.parse fileName + fun getsome (SOME x) = x - (* Typecheck and translate --> fragment list *) - val _ = R.fragList := [] - val frags = S.transProg absyn + fun emitproc out (F.PROC{body,frame}) = + let val _ = print ("emit " ^ F.name frame ^ "\n") + (* val _ = Printtree.printtree(out,body); *) + val stms = Canon.linearize body + (* val _ = app (fn s => Printtree.printtree(out,s)) stms; *) + val stms' = Canon.traceSchedule(Canon.basicBlocks stms) + val instrs = List.concat(map (MIPSGen.codeGen frame) stms') + val format0 = Assem.format(Temp.makestring) + in app (fn i => TextIO.output(out,format0 i)) instrs + end + | emitproc out (F.STRING(lab,s)) = TextIO.output(out, F.string (lab,s)) + fun withOpenFile fname f = + let val out = TextIO.openOut fname + in (f out before TextIO.closeOut out) + handle e => (TextIO.closeOut out; raise e) + end - (* For testing: print the fragment list *) - fun printFragment (F.PROC ({body = body', frame = frame'})) = - (F.printFrame frame'; - Printtree.printtree (TextIO.stdOut, body'); - print "\n") - | printFragment (F.STRING (label', literal)) = - print ("[STRING] " ^ (Symbol.name label') ^ " \"" ^ literal ^ "\"\n") + fun compile filename = + let val absyn = Parse.parse filename + val frags = ((*FindEscape.prog absyn;*) S.transProg absyn) + in + withOpenFile (filename ^ ".s") + (fn out => (app (emitproc out) frags)) + end - in app printFragment frags; - frags - end end \ No newline at end of file diff --git a/mips/.cm/GUID/mipsframe.sml b/mips/.cm/GUID/mipsframe.sml new file mode 100644 index 0000000..614faaa --- /dev/null +++ b/mips/.cm/GUID/mipsframe.sml @@ -0,0 +1 @@ +guid-(sources.cm):mips/mipsframe.sml-1586560191.476 diff --git a/mips/.cm/GUID/mipsgen.sml b/mips/.cm/GUID/mipsgen.sml new file mode 100644 index 0000000..44a4613 --- /dev/null +++ b/mips/.cm/GUID/mipsgen.sml @@ -0,0 +1 @@ +guid-(sources.cm):mips/mipsgen.sml-1586560191.749 diff --git a/mips/.cm/SKEL/mipsframe.sml b/mips/.cm/SKEL/mipsframe.sml new file mode 100644 index 0000000..3915187 --- /dev/null +++ b/mips/.cm/SKEL/mipsframe.sml @@ -0,0 +1,2 @@ +Skeleton 5 +d4f4d"Int"d"Temp"ä¢Tree"d"Symbol"ad"T"gp1’ad"Err"gp1d"ErrorMsg"ad"MIPSFrame"jh0gp1c"FRAME" \ No newline at end of file diff --git a/mips/.cm/SKEL/mipsgen.sml b/mips/.cm/SKEL/mipsgen.sml new file mode 100644 index 0000000..e2e23a9 --- /dev/null +++ b/mips/.cm/SKEL/mipsgen.sml @@ -0,0 +1,2 @@ +Skeleton 5 +d2f2d"Temp"d"Assem"ad"MIPSGen"jh1ad"Frame"gp1d"MIPSFrame"gp1c"CODEGEN" \ No newline at end of file diff --git a/mips/.cm/amd64-unix/mipsframe.sml b/mips/.cm/amd64-unix/mipsframe.sml new file mode 100644 index 0000000..0c52f83 Binary files /dev/null and b/mips/.cm/amd64-unix/mipsframe.sml differ diff --git a/mips/.cm/amd64-unix/mipsgen.sml b/mips/.cm/amd64-unix/mipsgen.sml new file mode 100644 index 0000000..c2e260e Binary files /dev/null and b/mips/.cm/amd64-unix/mipsgen.sml differ diff --git a/frame/mipsframe.sml b/mips/mipsframe.sml similarity index 95% rename from frame/mipsframe.sml rename to mips/mipsframe.sml index 2fb327b..e1dfe1c 100644 --- a/frame/mipsframe.sml +++ b/mips/mipsframe.sml @@ -21,7 +21,7 @@ struct val argRegisters = 4 (* Getters *) - fun name {name = name, formals = _, numLocals = _, curOffset = _} = name + fun name {name = symbol, formals = _, numLocals = _, curOffset = _} = Symbol.name symbol fun formals {name = _, formals = formals, numLocals = _, curOffset = _} = formals @@ -51,6 +51,7 @@ struct InFrame offset => Tree.MEM(Tree.BINOP(Tree.PLUS, frameaddr, Tree.CONST offset)) | InReg temp => Tree.TEMP(temp) + fun string (label, str) = str fun nextFrame {name, formals} = let fun allocateFormals(offset, [], allocList, numRegs) = allocList diff --git a/mips/mipsgen.sml b/mips/mipsgen.sml new file mode 100644 index 0000000..43a0155 --- /dev/null +++ b/mips/mipsgen.sml @@ -0,0 +1,7 @@ +structure MIPSGen : CODEGEN = +struct + structure Frame = MIPSFrame + fun codeGen (frame) = let fun treeToAssem (stm) = [Assem.LABEL {assem="", lab=Temp.newlabel ()}] + in treeToAssem + end +end \ No newline at end of file diff --git a/old_main.sml b/old_main.sml new file mode 100644 index 0000000..3166cf9 --- /dev/null +++ b/old_main.sml @@ -0,0 +1,29 @@ +structure Main = +struct + structure F = MIPSFrame + structure R = Translate (F) + structure S = Semant (R) + + fun main (fileName : string) = + let val _ = () + + (* Lex and Parse --> AST *) + val absyn = Parse.parse fileName + + (* Typecheck and translate --> fragment list *) + val _ = R.fragList := [] + val frags = S.transProg absyn + + + (* For testing: print the fragment list *) + fun printFragment (F.PROC ({body = body', frame = frame'})) = + (F.printFrame frame'; + Printtree.printtree (TextIO.stdOut, body'); + print "\n") + | printFragment (F.STRING (label', literal)) = + print ("[STRING] " ^ (Symbol.name label') ^ " \"" ^ literal ^ "\"\n") + + in app printFragment frags; + frags + end +end \ No newline at end of file diff --git a/parser/.cm/amd64-unix/parse.sml b/parser/.cm/amd64-unix/parse.sml index f0300fb..03f4f3d 100644 Binary files a/parser/.cm/amd64-unix/parse.sml and b/parser/.cm/amd64-unix/parse.sml differ diff --git a/parser/.cm/amd64-unix/tiger.grm.sml b/parser/.cm/amd64-unix/tiger.grm.sml index 254565f..3b01ebe 100644 Binary files a/parser/.cm/amd64-unix/tiger.grm.sml and b/parser/.cm/amd64-unix/tiger.grm.sml differ diff --git a/run.sml b/run.sml index 5729acd..f066a40 100644 --- a/run.sml +++ b/run.sml @@ -3,7 +3,7 @@ CM.make "sources.cm"; fun runTest (testCount) = let val filename = (concat ["testcases/test", Int.toString testCount ,".tig"]) in - Main.main filename; + Main.compile filename; () end; diff --git a/runtime.c b/runtime.c new file mode 100644 index 0000000..106ad56 --- /dev/null +++ b/runtime.c @@ -0,0 +1,109 @@ +#undef __STDC__ +#include + + +int *initArray(int size, int init) +{int i; + int *a = (int *)malloc(size*sizeof(int)); + for(i=0;ilength!=t->length) return 0; + for(i=0;ilength;i++) if (s->chars[i]!=t->chars[i]) return 0; + return 1; +} + +void print(struct string *s) +{int i; unsigned char *p=s->chars; + for(i=0;ilength;i++,p++) putchar(*p); +} + +void flush() +{ + fflush(stdout); +} + +struct string consts[256]; +struct string empty={0,""}; + +int main() +{int i; + for(i=0;i<256;i++) + {consts[i].length=1; + consts[i].chars[0]=i; + } + return tigermain(0 /* static link!? */); +} + +int ord(struct string *s) +{ + if (s->length==0) return -1; + else return s->chars[0]; +} + +struct string *chr(int i) +{ + if (i<0 || i>=256) + {printf("chr(%d) out of range\n",i); exit(1);} + return consts+i; +} + +int size(struct string *s) +{ + return s->length; +} + +struct string *substring(struct string *s, int first, int n) +{ + if (first<0 || first+n>s->length) + {printf("substring([%d],%d,%d) out of range\n",s->length,first,n); + exit(1);} + if (n==1) return consts+s->chars[first]; + {struct string *t = (struct string *)malloc(sizeof(int)+n); + int i; + t->length=n; + for(i=0;ichars[i]=s->chars[first+i]; + return t; + } +} + +struct string *concat(struct string *a, struct string *b) +{ + if (a->length==0) return b; + else if (b->length==0) return a; + else {int i, n=a->length+b->length; + struct string *t = (struct string *)malloc(sizeof(int)+n); + t->length=n; + for (i=0;ilength;i++) + t->chars[i]=a->chars[i]; + for(i=0;ilength;i++) + t->chars[i+a->length]=b->chars[i]; + return t; + } +} + +int not(int i) +{ return !i; +} + +#undef getchar + +struct string *getchar() +{int i=getc(stdin); + if (i==EOF) return ∅ + else return consts+i; +} diff --git a/semant/.cm/amd64-unix/env.sig b/semant/.cm/amd64-unix/env.sig index dec8fa2..e7dafc6 100644 Binary files a/semant/.cm/amd64-unix/env.sig and b/semant/.cm/amd64-unix/env.sig differ diff --git a/semant/.cm/amd64-unix/env.sml b/semant/.cm/amd64-unix/env.sml index 2c16e4d..a3f229e 100644 Binary files a/semant/.cm/amd64-unix/env.sml and b/semant/.cm/amd64-unix/env.sml differ diff --git a/semant/.cm/amd64-unix/semant.sig b/semant/.cm/amd64-unix/semant.sig index 412fcfe..1fba2c0 100644 Binary files a/semant/.cm/amd64-unix/semant.sig and b/semant/.cm/amd64-unix/semant.sig differ diff --git a/semant/.cm/amd64-unix/semant.sml b/semant/.cm/amd64-unix/semant.sml index ac9f7c4..ecf3791 100644 Binary files a/semant/.cm/amd64-unix/semant.sml and b/semant/.cm/amd64-unix/semant.sml differ diff --git a/sources.cm b/sources.cm index 6906eb2..b3d55fe 100644 --- a/sources.cm +++ b/sources.cm @@ -21,10 +21,10 @@ Group is parser/parse.sml (* Semantic Analysis *) - tree/table.sig - tree/table.sml + table/table.sig + table/table.sml - tree/symbol.sml + table/symbol.sml (* IR *) @@ -45,5 +45,11 @@ Group is IR/temp.sig IR/temp.sml - frame/frame.sig - frame/mipsframe.sml \ No newline at end of file + assem/frame.sig + mips/mipsframe.sml + + assem/codegen.sig + mips/mipsgen.sml + + assem/canon.sml + assem/assem.sml diff --git a/table/.cm/GUID/symbol.sml b/table/.cm/GUID/symbol.sml new file mode 100644 index 0000000..7dd2a3c --- /dev/null +++ b/table/.cm/GUID/symbol.sml @@ -0,0 +1 @@ +guid-(sources.cm):table/symbol.sml-1586561158.678 diff --git a/table/.cm/GUID/table.sig b/table/.cm/GUID/table.sig new file mode 100644 index 0000000..76f1d31 --- /dev/null +++ b/table/.cm/GUID/table.sig @@ -0,0 +1 @@ +guid-(sources.cm):table/table.sig-1586561158.655 diff --git a/table/.cm/GUID/table.sml b/table/.cm/GUID/table.sml new file mode 100644 index 0000000..de39979 --- /dev/null +++ b/table/.cm/GUID/table.sml @@ -0,0 +1 @@ +guid-(sources.cm):table/table.sml-1586561158.659 diff --git a/table/.cm/SKEL/symbol.sml b/table/.cm/SKEL/symbol.sml new file mode 100644 index 0000000..e65b089 --- /dev/null +++ b/table/.cm/SKEL/symbol.sml @@ -0,0 +1,2 @@ +Skeleton 5 +d3f1d"HashString"ać¢SYMBOL"č0ad"Symbol"jh2ad"H"gp1d"HashTable"ad"Table"j’gp1e"IntMapTable"gp1’ \ No newline at end of file diff --git a/table/.cm/SKEL/table.sig b/table/.cm/SKEL/table.sig new file mode 100644 index 0000000..219d7e8 --- /dev/null +++ b/table/.cm/SKEL/table.sig @@ -0,0 +1,2 @@ +Skeleton 5 +ac"TABLE"h0 \ No newline at end of file diff --git a/table/.cm/SKEL/table.sml b/table/.cm/SKEL/table.sml new file mode 100644 index 0000000..67918f7 --- /dev/null +++ b/table/.cm/SKEL/table.sml @@ -0,0 +1,2 @@ +Skeleton 5 +d2f1d"IntBinaryMap"ae"IntMapTable"jh0gp1c"TABLE" \ No newline at end of file diff --git a/table/.cm/amd64-unix/symbol.sml b/table/.cm/amd64-unix/symbol.sml new file mode 100644 index 0000000..be8a511 Binary files /dev/null and b/table/.cm/amd64-unix/symbol.sml differ diff --git a/table/.cm/amd64-unix/table.sig b/table/.cm/amd64-unix/table.sig new file mode 100644 index 0000000..e9119e7 Binary files /dev/null and b/table/.cm/amd64-unix/table.sig differ diff --git a/table/.cm/amd64-unix/table.sml b/table/.cm/amd64-unix/table.sml new file mode 100644 index 0000000..8c913a4 Binary files /dev/null and b/table/.cm/amd64-unix/table.sml differ diff --git a/tree/symbol.sml b/table/symbol.sml similarity index 100% rename from tree/symbol.sml rename to table/symbol.sml diff --git a/tree/table.sig b/table/table.sig similarity index 100% rename from tree/table.sig rename to table/table.sig diff --git a/tree/table.sml b/table/table.sml similarity index 100% rename from tree/table.sml rename to table/table.sml diff --git a/testcases/test1.tig.s b/testcases/test1.tig.s new file mode 100644 index 0000000..e69de29 diff --git a/tree/.cm/amd64-unix/printtree.sml b/tree/.cm/amd64-unix/printtree.sml index 05f4fcd..f3d5519 100644 Binary files a/tree/.cm/amd64-unix/printtree.sml and b/tree/.cm/amd64-unix/printtree.sml differ diff --git a/tree/.cm/amd64-unix/tree.sml b/tree/.cm/amd64-unix/tree.sml index 174304f..375229e 100644 Binary files a/tree/.cm/amd64-unix/tree.sml and b/tree/.cm/amd64-unix/tree.sml differ diff --git a/tree/tree.sml b/tree/tree.sml index e29390b..5ce4542 100644 --- a/tree/tree.sml +++ b/tree/tree.sml @@ -25,8 +25,8 @@ datatype stm = SEQ of stm * stm and relop = EQ | NE | LT | GT | LE | GE | ULT | ULE | UGT | UGE - (* val notRel : relop -> relop - val commute: relop -> relop *) + val notRel : relop -> relop + val commute: relop -> relop end structure Tree : TREE = @@ -56,5 +56,18 @@ datatype stm = SEQ of stm * stm and relop = EQ | NE | LT | GT | LE | GE | ULT | ULE | UGT | UGE + fun notRel (_) = EQ (* Needs to be implemented *) + + fun commute (EQ) = NE + | commute (NE) = EQ + | commute (LT) = GT + | commute (GT) = LT + | commute (LE) = GE + | commute (GE) = LE + | commute (ULT) = UGT + | commute (UGT) = ULT + | commute (ULE) = UGE + | commute (UGE) = ULE + end