-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
hj110
committed
Apr 20, 2021
1 parent
83c14e3
commit 5ca9eae
Showing
343 changed files
with
59,889 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,57 @@ | ||
# Tiger | ||
This repository is created for Tiger Compiler. | ||
# ECE553Project | ||
|
||
Group members: | ||
|
||
Tianle Zhang (tz94), Hao Jiang (hj110) and Yuchuan Li (yl645). | ||
|
||
### HW1: lexer | ||
Please see the directory "compiler/lexer". | ||
|
||
### HW2: parser | ||
Please see the directory "compiler/parser". | ||
|
||
### HW3: semantic analysis | ||
Please see the directory "compiler/semanalysis". | ||
|
||
### HW4: IR | ||
|
||
Please see the directory "compiler/ir". | ||
|
||
### HW5: Instruction Selection | ||
|
||
Please see the directory "compiler/ins_sel". | ||
|
||
### Liveness, Register Allocation, Working Compiler | ||
|
||
Please see the directory "compiler/reg_alloc". | ||
|
||
|
||
|
||
## How to Run | ||
```shell | ||
cd ece553project/compiler/reg_alloc | ||
``` | ||
|
||
To run a single test case: | ||
|
||
```shell | ||
./autotest.sh xxx.tig | ||
``` | ||
|
||
To run the entire test suit: | ||
|
||
``` | ||
./autotest.sh 2>&1 >result.out | ||
``` | ||
|
||
**Generated files:** | ||
|
||
`xxx.out` -- Message produced during the compilation, including compile errors if the tiger code is wrong. | ||
|
||
`xxx.s` -- Generated MIPS assemly without library functions in `runtime.s`. | ||
|
||
`xxx.tmp.s` -- `xxx.s` combined with `runtime.s` & `sysspim.s`. Can be executed by the command: | ||
|
||
``` | ||
spim -file xxx.tmp.s | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
type id = string | ||
|
||
datatype binop = Plus | Minus | Times | Div | ||
|
||
datatype stm = CompoundStm of stm * stm | ||
| AssignStm of id * exp | ||
| PrintStm of exp list | ||
|
||
and exp = IdExp of id | ||
| NumExp of int | ||
| OpExp of exp * binop * exp | ||
| EseqExp of stm * exp | ||
val prog = | ||
CompoundStm(AssignStm("a",OpExp(NumExp 5, Plus, NumExp 3)), | ||
CompoundStm(AssignStm("b", | ||
EseqExp(PrintStm[IdExp"a",OpExp(IdExp"a", Minus,NumExp 1)], | ||
OpExp(NumExp 10, Times, IdExp"a"))), | ||
PrintStm[IdExp "b"])) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#undef __STDC__ | ||
#include <stdio.h> | ||
|
||
|
||
int *initArray(int size, int init) | ||
{int i; | ||
int *a = (int *)malloc(size*sizeof(int)); | ||
for(i=0;i<size;i++) a[i]=init; | ||
return a; | ||
} | ||
|
||
int *allocRecord(int size) | ||
{int i; | ||
int *p, *a; | ||
p = a = (int *)malloc(size); | ||
for(i=0;i<size;i+=sizeof(int)) *p++ = 0; | ||
return a; | ||
} | ||
|
||
struct string {int length; unsigned char chars[1];}; | ||
|
||
int stringEqual(struct string *s, struct string *t) | ||
{int i; | ||
if (s==t) return 1; | ||
if (s->length!=t->length) return 0; | ||
for(i=0;i<s->length;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;i<s->length;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;i<n;i++) t->chars[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;i<a->length;i++) | ||
t->chars[i]=a->chars[i]; | ||
for(i=0;i<b->length;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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
structure Parse = | ||
struct | ||
fun parse filename = | ||
let val file = TextIO.openIn filename | ||
fun get _ = TextIO.input file | ||
val lexer = Mlex.makeLexer get | ||
fun do_it() = | ||
let val t = lexer() | ||
in print t; print "\n"; | ||
if substring(t,0,3)="EOF" then () else do_it() | ||
end | ||
in do_it(); | ||
TextIO.closeIn file | ||
end | ||
|
||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
signature ERRORMSG = | ||
sig | ||
val anyErrors : bool ref | ||
val fileName : string ref | ||
val lineNum : int ref | ||
val linePos : int list ref | ||
val sourceStream : TextIO.instream ref | ||
val error : int -> string -> unit | ||
exception Error | ||
val impossible : string -> 'a (* raises Error *) | ||
val reset : unit -> unit | ||
end | ||
|
||
structure ErrorMsg : ERRORMSG = | ||
struct | ||
|
||
val anyErrors = ref false | ||
val fileName = ref "" | ||
val lineNum = ref 1 | ||
val linePos = ref [1] | ||
val sourceStream = ref TextIO.stdIn | ||
|
||
fun reset() = (anyErrors:=false; | ||
fileName:=""; | ||
lineNum:=1; | ||
linePos:=[1]; | ||
sourceStream:=TextIO.stdIn) | ||
|
||
exception Error | ||
|
||
fun error pos (msg:string) = | ||
let fun look(a::rest,n) = | ||
if a<pos then app print [":", | ||
Int.toString n, | ||
".", | ||
Int.toString (pos-a)] | ||
else look(rest,n-1) | ||
| look _ = print "0.0" | ||
in anyErrors := true; | ||
print (!fileName); | ||
look(!linePos,!lineNum); | ||
print ":"; | ||
print msg; | ||
print "\n" | ||
end | ||
|
||
fun impossible msg = | ||
(app print ["Error: Compiler bug: ",msg,"\n"]; | ||
TextIO.flushOut TextIO.stdOut; | ||
raise Error) | ||
|
||
end (* structure ErrorMsg *) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Group is | ||
|
||
driver.sml | ||
errormsg.sml | ||
tokens.sig | ||
tokens.sml | ||
tiger.lex | ||
$/smlnj-lib.cm | ||
$/basis.cm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
type pos = int | ||
type lexresult = Tokens.token | ||
|
||
val lineNum = ErrorMsg.lineNum | ||
val linePos = ErrorMsg.linePos | ||
fun err(p1,p2) = ErrorMsg.error p1 | ||
|
||
fun eof() = let val pos = hd(!linePos) in Tokens.EOF(pos,pos) end | ||
|
||
|
||
%% | ||
%% | ||
\n => (lineNum := !lineNum+1; linePos := yypos :: !linePos; continue()); | ||
"," => (Tokens.COMMA(yypos,yypos+1)); | ||
var => (Tokens.VAR(yypos,yypos+3)); | ||
"123" => (Tokens.INT(123,yypos,yypos+3)); | ||
. => (ErrorMsg.error yypos ("illegal character " ^ yytext); continue()); | ||
|
Oops, something went wrong.