Add the tiger source code bundle from the book site
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
parent
915660c8a7
commit
33d8bac511
87 changed files with 3252 additions and 0 deletions
20
tiger/chap1/slp.sml
Normal file
20
tiger/chap1/slp.sml
Normal file
|
|
@ -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"]))
|
||||
|
||||
|
||||
80
tiger/chap10/graph.sml
Normal file
80
tiger/chap10/graph.sml
Normal file
|
|
@ -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
|
||||
|
||||
109
tiger/chap12/runtime.c
Normal file
109
tiger/chap12/runtime.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
17
tiger/chap2/driver.sml
Normal file
17
tiger/chap2/driver.sml
Normal file
|
|
@ -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
|
||||
|
||||
53
tiger/chap2/errormsg.sml
Normal file
53
tiger/chap2/errormsg.sml
Normal file
|
|
@ -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 *)
|
||||
|
||||
8
tiger/chap2/sources.cm
Normal file
8
tiger/chap2/sources.cm
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Group is
|
||||
|
||||
driver.sml
|
||||
errormsg.sml
|
||||
tokens.sig
|
||||
tokens.sml
|
||||
tiger.lex
|
||||
smlnj-lib.cm
|
||||
18
tiger/chap2/tiger.lex
Normal file
18
tiger/chap2/tiger.lex
Normal file
|
|
@ -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());
|
||||
|
||||
49
tiger/chap2/tokens.sig
Normal file
49
tiger/chap2/tokens.sig
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
signature Tiger_TOKENS =
|
||||
sig
|
||||
type linenum (* = int *)
|
||||
type token
|
||||
val TYPE: linenum * linenum -> token
|
||||
val VAR: linenum * linenum -> token
|
||||
val FUNCTION: linenum * linenum -> token
|
||||
val BREAK: linenum * linenum -> token
|
||||
val OF: linenum * linenum -> token
|
||||
val END: linenum * linenum -> token
|
||||
val IN: linenum * linenum -> token
|
||||
val NIL: linenum * linenum -> token
|
||||
val LET: linenum * linenum -> token
|
||||
val DO: linenum * linenum -> token
|
||||
val TO: linenum * linenum -> token
|
||||
val FOR: linenum * linenum -> token
|
||||
val WHILE: linenum * linenum -> token
|
||||
val ELSE: linenum * linenum -> token
|
||||
val THEN: linenum * linenum -> token
|
||||
val IF: linenum * linenum -> token
|
||||
val ARRAY: linenum * linenum -> token
|
||||
val ASSIGN: linenum * linenum -> token
|
||||
val OR: linenum * linenum -> token
|
||||
val AND: linenum * linenum -> token
|
||||
val GE: linenum * linenum -> token
|
||||
val GT: linenum * linenum -> token
|
||||
val LE: linenum * linenum -> token
|
||||
val LT: linenum * linenum -> token
|
||||
val NEQ: linenum * linenum -> token
|
||||
val EQ: linenum * linenum -> token
|
||||
val DIVIDE: linenum * linenum -> token
|
||||
val TIMES: linenum * linenum -> token
|
||||
val MINUS: linenum * linenum -> token
|
||||
val PLUS: linenum * linenum -> token
|
||||
val DOT: linenum * linenum -> token
|
||||
val RBRACE: linenum * linenum -> token
|
||||
val LBRACE: linenum * linenum -> token
|
||||
val RBRACK: linenum * linenum -> token
|
||||
val LBRACK: linenum * linenum -> token
|
||||
val RPAREN: linenum * linenum -> token
|
||||
val LPAREN: linenum * linenum -> token
|
||||
val SEMICOLON: linenum * linenum -> token
|
||||
val COLON: linenum * linenum -> token
|
||||
val COMMA: linenum * linenum -> token
|
||||
val STRING: (string) * linenum * linenum -> token
|
||||
val INT: (int) * linenum * linenum -> token
|
||||
val ID: (string) * linenum * linenum -> token
|
||||
val EOF: linenum * linenum -> token
|
||||
end
|
||||
51
tiger/chap2/tokens.sml
Normal file
51
tiger/chap2/tokens.sml
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
structure Tokens : Tiger_TOKENS =
|
||||
struct
|
||||
(* A "scaffold" structure for debugging lexers. *)
|
||||
|
||||
type linenum = int
|
||||
type token = string
|
||||
fun TYPE(i,j) = "TYPE " ^ Int.toString(i)
|
||||
fun VAR(i,j) = "VAR " ^ Int.toString(i)
|
||||
fun FUNCTION(i,j) = "FUNCTION " ^ Int.toString(i)
|
||||
fun BREAK(i,j) = "BREAK " ^ Int.toString(i)
|
||||
fun OF(i,j) = "OF " ^ Int.toString(i)
|
||||
fun END(i,j) = "END " ^ Int.toString(i)
|
||||
fun IN(i,j) = "IN " ^ Int.toString(i)
|
||||
fun NIL(i,j) = "NIL " ^ Int.toString(i)
|
||||
fun LET(i,j) = "LET " ^ Int.toString(i)
|
||||
fun DO(i,j) = "DO " ^ Int.toString(i)
|
||||
fun TO(i,j) = "TO " ^ Int.toString(i)
|
||||
fun FOR(i,j) = "FOR " ^ Int.toString(i)
|
||||
fun WHILE(i,j) = "WHILE " ^ Int.toString(i)
|
||||
fun ELSE(i,j) = "ELSE " ^ Int.toString(i)
|
||||
fun THEN(i,j) = "THEN " ^ Int.toString(i)
|
||||
fun IF(i,j) = "IF " ^ Int.toString(i)
|
||||
fun ARRAY(i,j) = "ARRAY " ^ Int.toString(i)
|
||||
fun ASSIGN(i,j) = "ASSIGN " ^ Int.toString(i)
|
||||
fun OR(i,j) = "OR " ^ Int.toString(i)
|
||||
fun AND(i,j) = "AND " ^ Int.toString(i)
|
||||
fun GE(i,j) = "GE " ^ Int.toString(i)
|
||||
fun GT(i,j) = "GT " ^ Int.toString(i)
|
||||
fun LE(i,j) = "LE " ^ Int.toString(i)
|
||||
fun LT(i,j) = "LT " ^ Int.toString(i)
|
||||
fun NEQ(i,j) = "NEQ " ^ Int.toString(i)
|
||||
fun EQ(i,j) = "EQ " ^ Int.toString(i)
|
||||
fun DIVIDE(i,j) = "DIVIDE " ^ Int.toString(i)
|
||||
fun TIMES(i,j) = "TIMES " ^ Int.toString(i)
|
||||
fun MINUS(i,j) = "MINUS " ^ Int.toString(i)
|
||||
fun PLUS(i,j) = "PLUS " ^ Int.toString(i)
|
||||
fun DOT(i,j) = "DOT " ^ Int.toString(i)
|
||||
fun RBRACE(i,j) = "RBRACE " ^ Int.toString(i)
|
||||
fun LBRACE(i,j) = "LBRACE " ^ Int.toString(i)
|
||||
fun RBRACK(i,j) = "RBRACK " ^ Int.toString(i)
|
||||
fun LBRACK(i,j) = "LBRACK " ^ Int.toString(i)
|
||||
fun RPAREN(i,j) = "RPAREN " ^ Int.toString(i)
|
||||
fun LPAREN(i,j) = "LPAREN " ^ Int.toString(i)
|
||||
fun SEMICOLON(i,j) = "SEMICOLON " ^ Int.toString(i)
|
||||
fun COLON(i,j) = "COLON " ^ Int.toString(i)
|
||||
fun COMMA(i,j) = "COMMA " ^ Int.toString(i)
|
||||
fun STRING(s,i,j) = "STRING("^s^") " ^ Int.toString(i)
|
||||
fun INT(c,i,j) = "INT("^Int.toString(c)^") " ^ Int.toString(i)
|
||||
fun ID(s,i,j) = "ID("^s^") " ^ Int.toString(i)
|
||||
fun EOF(i,j) = "EOF " ^ Int.toString(i)
|
||||
end
|
||||
53
tiger/chap3/errormsg.sml
Normal file
53
tiger/chap3/errormsg.sml
Normal file
|
|
@ -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 *)
|
||||
|
||||
22
tiger/chap3/parsetest.sml
Normal file
22
tiger/chap3/parsetest.sml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
structure Parse : sig val parse : string -> unit end =
|
||||
struct
|
||||
structure TigerLrVals = TigerLrValsFun(structure Token = LrParser.Token)
|
||||
structure Lex = TigerLexFun(structure Tokens = TigerLrVals.Tokens)
|
||||
structure TigerP = Join(structure ParserData = TigerLrVals.ParserData
|
||||
structure Lex=Lex
|
||||
structure LrParser = LrParser)
|
||||
fun parse filename =
|
||||
let val _ = (ErrorMsg.reset(); ErrorMsg.fileName := filename)
|
||||
val file = TextIO.openIn filename
|
||||
fun get _ = TextIO.input file
|
||||
fun parseerror(s,p1,p2) = ErrorMsg.error p1 s
|
||||
val lexer = LrParser.Stream.streamify (Lex.makeLexer get)
|
||||
val (absyn, _) = TigerP.parse(30,lexer,parseerror,())
|
||||
in TextIO.closeIn file;
|
||||
absyn
|
||||
end handle LrParser.ParseError => raise ErrorMsg.Error
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
9
tiger/chap3/sources.cm
Normal file
9
tiger/chap3/sources.cm
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Group is
|
||||
|
||||
tiger.lex
|
||||
errormsg.sml
|
||||
parsetest.sml
|
||||
tiger.grm
|
||||
smlnj-lib.cm
|
||||
ml-yacc-lib.cm
|
||||
|
||||
38
tiger/chap3/tiger.grm
Normal file
38
tiger/chap3/tiger.grm
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
%%
|
||||
%term
|
||||
EOF
|
||||
| ID of string
|
||||
| INT of int | STRING of string
|
||||
| COMMA | COLON | SEMICOLON | LPAREN | RPAREN | LBRACK | RBRACK
|
||||
| LBRACE | RBRACE | DOT
|
||||
| PLUS | MINUS | TIMES | DIVIDE | EQ | NEQ | LT | LE | GT | GE
|
||||
| AND | OR | ASSIGN
|
||||
| ARRAY | IF | THEN | ELSE | WHILE | FOR | TO | DO | LET | IN | END | OF
|
||||
| BREAK | NIL
|
||||
| FUNCTION | VAR | TYPE
|
||||
|
||||
%nonterm exp | program
|
||||
|
||||
%pos int
|
||||
%verbose
|
||||
%start program
|
||||
%eop EOF
|
||||
%noshift EOF
|
||||
|
||||
%name Tiger
|
||||
|
||||
%keyword WHILE FOR TO BREAK LET IN END FUNCTION VAR TYPE ARRAY IF THEN ELSE
|
||||
DO OF NIL
|
||||
|
||||
%prefer THEN ELSE LPAREN
|
||||
|
||||
%value ID ("bogus")
|
||||
%value INT (1)
|
||||
%value STRING ("")
|
||||
|
||||
%%
|
||||
|
||||
program : exp ()
|
||||
|
||||
|
||||
exp: ()
|
||||
988
tiger/chap3/tiger.lex.sml
Normal file
988
tiger/chap3/tiger.lex.sml
Normal file
|
|
@ -0,0 +1,988 @@
|
|||
(* Copyright (c) 1997 Andrew W. Appel. *)
|
||||
functor TigerLexFun(structure Tokens : Tiger_TOKENS)=
|
||||
struct
|
||||
structure UserDeclarations =
|
||||
struct
|
||||
open ErrorMsg;
|
||||
|
||||
type svalue = Tokens.svalue
|
||||
type pos = int
|
||||
type ('a,'b) token = ('a,'b) Tokens.token
|
||||
type lexresult = (svalue,pos) token
|
||||
|
||||
fun inc x = x := !x + 1
|
||||
fun dec x = x := !x - 1
|
||||
|
||||
val stringstart = ref 0
|
||||
val charlist = ref (nil: char list)
|
||||
val lineNum = ErrorMsg.lineNum
|
||||
val linePos = ErrorMsg.linePos
|
||||
val comLevel = ref 0
|
||||
fun err(p1,p2) = ErrorMsg.error p1
|
||||
|
||||
val eof = fn () =>
|
||||
let val pos = Int.max(!stringstart+2, hd(!linePos))
|
||||
in if !comLevel>0 then err (!stringstart,pos) "unclosed comment"
|
||||
else ();
|
||||
Tokens.EOF(pos,pos)
|
||||
end
|
||||
fun addString (s:char) = charlist := s :: (!charlist)
|
||||
fun makeString () = (implode(rev(!charlist)) before charlist := nil)
|
||||
|
||||
fun makeInt s =
|
||||
foldl (fn (c,a) => a*10 + ord c - ord #"0") 0 (explode s)
|
||||
|
||||
|
||||
end (* end of user routines *)
|
||||
exception LexError (* raised if illegal leaf action tried *)
|
||||
structure Internal =
|
||||
struct
|
||||
|
||||
datatype yyfinstate = N of int
|
||||
type statedata = {fin : yyfinstate list, trans: string}
|
||||
(* transition & final state table *)
|
||||
val tab = let
|
||||
val s = [
|
||||
(0,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(1,
|
||||
"\010\010\010\010\010\010\010\010\010\096\098\010\096\010\010\010\
|
||||
\\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\
|
||||
\\096\010\095\010\010\010\094\010\092\091\089\088\087\086\085\084\
|
||||
\\082\082\082\082\082\082\082\082\082\082\080\079\076\075\073\010\
|
||||
\\010\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\
|
||||
\\014\014\014\014\014\014\014\014\014\014\014\072\010\071\010\010\
|
||||
\\010\066\061\014\059\053\043\014\014\040\014\014\037\014\034\032\
|
||||
\\014\014\014\014\024\014\021\016\014\014\014\013\012\011\010\010\
|
||||
\\009"
|
||||
),
|
||||
(3,
|
||||
"\099\099\099\099\099\099\099\099\099\099\104\099\099\099\099\099\
|
||||
\\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\
|
||||
\\099\099\099\099\099\099\099\099\102\099\100\099\099\099\099\099\
|
||||
\\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\
|
||||
\\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\
|
||||
\\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\
|
||||
\\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\
|
||||
\\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\099\
|
||||
\\099"
|
||||
),
|
||||
(5,
|
||||
"\105\105\105\105\105\105\105\105\105\105\119\105\105\105\105\105\
|
||||
\\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\
|
||||
\\105\105\118\105\105\105\105\105\105\105\105\105\105\105\105\105\
|
||||
\\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\
|
||||
\\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\
|
||||
\\105\105\105\105\105\105\105\105\105\105\105\105\106\105\105\105\
|
||||
\\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\
|
||||
\\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\105\
|
||||
\\105"
|
||||
),
|
||||
(7,
|
||||
"\120\120\120\120\120\120\120\120\120\122\124\120\122\120\120\120\
|
||||
\\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\
|
||||
\\122\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\
|
||||
\\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\
|
||||
\\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\
|
||||
\\120\120\120\120\120\120\120\120\120\120\120\120\121\120\120\120\
|
||||
\\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\
|
||||
\\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\120\
|
||||
\\120"
|
||||
),
|
||||
(14,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(16,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\017\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(17,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\018\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(18,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\019\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(19,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\020\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(21,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\022\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(22,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\023\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(24,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\029\015\015\015\015\015\015\028\
|
||||
\\015\015\015\015\015\015\015\015\015\025\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(25,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\026\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(26,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\027\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(29,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\030\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(30,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\031\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(32,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\033\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(34,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\035\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(35,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\036\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(37,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\038\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(38,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\039\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(40,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\042\015\015\015\015\015\015\015\041\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(43,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\051\
|
||||
\\015\015\015\015\015\044\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(44,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\045\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(45,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\046\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(46,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\047\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(47,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\048\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(48,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\049\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(49,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\050\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(51,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\052\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(53,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\056\015\054\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(54,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\055\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(56,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\057\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(57,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\058\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(59,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\060\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(61,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\062\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(62,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\063\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(63,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\064\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(64,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\065\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(66,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\067\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(67,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\068\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(68,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\069\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(69,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\015\
|
||||
\\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\
|
||||
\\015\015\015\015\015\015\015\015\015\070\015\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(73,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\074\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(76,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\078\077\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(80,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\081\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(82,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\083\083\083\083\083\083\083\083\083\083\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(89,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\090\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(92,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\093\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(96,
|
||||
"\000\000\000\000\000\000\000\000\000\097\000\000\097\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\097\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(100,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\101\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(102,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\103\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(106,
|
||||
"\000\000\000\000\000\000\000\000\000\116\117\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\116\000\115\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\112\112\112\112\112\112\112\112\112\112\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\111\000\109\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\108\000\
|
||||
\\000\000\000\000\107\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(109,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\
|
||||
\\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(112,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\113\113\113\113\113\113\113\113\113\113\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(113,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\114\114\114\114\114\114\114\114\114\114\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(122,
|
||||
"\000\000\000\000\000\000\000\000\000\123\000\000\123\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\123\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
|
||||
\\000"
|
||||
),
|
||||
(0, "")]
|
||||
fun f x = x
|
||||
val s = map f (rev (tl (rev s)))
|
||||
exception LexHackingError
|
||||
fun look ((j,x)::r, i) = if i = j then x else look(r, i)
|
||||
| look ([], i) = raise LexHackingError
|
||||
fun g {fin=x, trans=i} = {fin=x, trans=look(s,i)}
|
||||
in Vector.fromList(map g
|
||||
[{fin = [], trans = 0},
|
||||
{fin = [(N 2)], trans = 1},
|
||||
{fin = [(N 2)], trans = 1},
|
||||
{fin = [], trans = 3},
|
||||
{fin = [], trans = 3},
|
||||
{fin = [], trans = 5},
|
||||
{fin = [], trans = 5},
|
||||
{fin = [(N 174)], trans = 7},
|
||||
{fin = [(N 174)], trans = 7},
|
||||
{fin = [(N 147),(N 149)], trans = 0},
|
||||
{fin = [(N 149)], trans = 0},
|
||||
{fin = [(N 10),(N 149)], trans = 0},
|
||||
{fin = [(N 36),(N 149)], trans = 0},
|
||||
{fin = [(N 8),(N 149)], trans = 0},
|
||||
{fin = [(N 134),(N 149)], trans = 14},
|
||||
{fin = [(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 16},
|
||||
{fin = [(N 134)], trans = 17},
|
||||
{fin = [(N 134)], trans = 18},
|
||||
{fin = [(N 134)], trans = 19},
|
||||
{fin = [(N 64),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 21},
|
||||
{fin = [(N 134)], trans = 22},
|
||||
{fin = [(N 101),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 24},
|
||||
{fin = [(N 134)], trans = 25},
|
||||
{fin = [(N 134)], trans = 26},
|
||||
{fin = [(N 106),(N 134)], trans = 14},
|
||||
{fin = [(N 84),(N 134)], trans = 14},
|
||||
{fin = [(N 134)], trans = 29},
|
||||
{fin = [(N 134)], trans = 30},
|
||||
{fin = [(N 120),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 32},
|
||||
{fin = [(N 131),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 34},
|
||||
{fin = [(N 134)], trans = 35},
|
||||
{fin = [(N 81),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 37},
|
||||
{fin = [(N 134)], trans = 38},
|
||||
{fin = [(N 74),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 40},
|
||||
{fin = [(N 77),(N 134)], trans = 14},
|
||||
{fin = [(N 115),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 43},
|
||||
{fin = [(N 134)], trans = 44},
|
||||
{fin = [(N 134)], trans = 45},
|
||||
{fin = [(N 134)], trans = 46},
|
||||
{fin = [(N 134)], trans = 47},
|
||||
{fin = [(N 134)], trans = 48},
|
||||
{fin = [(N 134)], trans = 49},
|
||||
{fin = [(N 97),(N 134)], trans = 14},
|
||||
{fin = [(N 134)], trans = 51},
|
||||
{fin = [(N 58),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 53},
|
||||
{fin = [(N 134)], trans = 54},
|
||||
{fin = [(N 88),(N 134)], trans = 14},
|
||||
{fin = [(N 134)], trans = 56},
|
||||
{fin = [(N 134)], trans = 57},
|
||||
{fin = [(N 125),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 59},
|
||||
{fin = [(N 128),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 61},
|
||||
{fin = [(N 134)], trans = 62},
|
||||
{fin = [(N 134)], trans = 63},
|
||||
{fin = [(N 134)], trans = 64},
|
||||
{fin = [(N 70),(N 134)], trans = 14},
|
||||
{fin = [(N 134),(N 149)], trans = 66},
|
||||
{fin = [(N 134)], trans = 67},
|
||||
{fin = [(N 134)], trans = 68},
|
||||
{fin = [(N 134)], trans = 69},
|
||||
{fin = [(N 112),(N 134)], trans = 14},
|
||||
{fin = [(N 14),(N 149)], trans = 0},
|
||||
{fin = [(N 12),(N 149)], trans = 0},
|
||||
{fin = [(N 46),(N 149)], trans = 73},
|
||||
{fin = [(N 51)], trans = 0},
|
||||
{fin = [(N 41),(N 149)], trans = 0},
|
||||
{fin = [(N 48),(N 149)], trans = 76},
|
||||
{fin = [(N 44)], trans = 0},
|
||||
{fin = [(N 54)], trans = 0},
|
||||
{fin = [(N 18),(N 149)], trans = 0},
|
||||
{fin = [(N 16),(N 149)], trans = 80},
|
||||
{fin = [(N 39)], trans = 0},
|
||||
{fin = [(N 137),(N 149)], trans = 82},
|
||||
{fin = [(N 137)], trans = 82},
|
||||
{fin = [(N 32),(N 149)], trans = 0},
|
||||
{fin = [(N 24),(N 149)], trans = 0},
|
||||
{fin = [(N 28),(N 149)], trans = 0},
|
||||
{fin = [(N 6),(N 149)], trans = 0},
|
||||
{fin = [(N 26),(N 149)], trans = 0},
|
||||
{fin = [(N 30),(N 149)], trans = 89},
|
||||
{fin = [(N 145)], trans = 0},
|
||||
{fin = [(N 22),(N 149)], trans = 0},
|
||||
{fin = [(N 20),(N 149)], trans = 92},
|
||||
{fin = [(N 142)], trans = 0},
|
||||
{fin = [(N 34),(N 149)], trans = 0},
|
||||
{fin = [(N 139),(N 149)], trans = 0},
|
||||
{fin = [(N 2),(N 149)], trans = 96},
|
||||
{fin = [(N 2)], trans = 96},
|
||||
{fin = [(N 4)], trans = 0},
|
||||
{fin = [(N 159)], trans = 0},
|
||||
{fin = [(N 159)], trans = 100},
|
||||
{fin = [(N 157)], trans = 0},
|
||||
{fin = [(N 159)], trans = 102},
|
||||
{fin = [(N 152)], trans = 0},
|
||||
{fin = [(N 154)], trans = 0},
|
||||
{fin = [(N 203)], trans = 0},
|
||||
{fin = [(N 201),(N 203)], trans = 106},
|
||||
{fin = [(N 181)], trans = 0},
|
||||
{fin = [(N 184)], trans = 0},
|
||||
{fin = [], trans = 109},
|
||||
{fin = [(N 194)], trans = 0},
|
||||
{fin = [(N 187)], trans = 0},
|
||||
{fin = [], trans = 112},
|
||||
{fin = [], trans = 113},
|
||||
{fin = [(N 199)], trans = 0},
|
||||
{fin = [(N 190)], trans = 0},
|
||||
{fin = [(N 169)], trans = 0},
|
||||
{fin = [(N 166)], trans = 0},
|
||||
{fin = [(N 161),(N 203)], trans = 0},
|
||||
{fin = [(N 163)], trans = 0},
|
||||
{fin = [(N 178)], trans = 0},
|
||||
{fin = [(N 176),(N 178)], trans = 0},
|
||||
{fin = [(N 174),(N 178)], trans = 122},
|
||||
{fin = [(N 174)], trans = 122},
|
||||
{fin = [(N 171)], trans = 0}])
|
||||
end
|
||||
structure StartStates =
|
||||
struct
|
||||
datatype yystartstate = STARTSTATE of int
|
||||
|
||||
(* start state definitions *)
|
||||
|
||||
val A = STARTSTATE 3;
|
||||
val F = STARTSTATE 7;
|
||||
val INITIAL = STARTSTATE 1;
|
||||
val S = STARTSTATE 5;
|
||||
|
||||
end
|
||||
type result = UserDeclarations.lexresult
|
||||
exception LexerError (* raised if illegal leaf action tried *)
|
||||
end
|
||||
|
||||
fun makeLexer yyinput =
|
||||
let
|
||||
val yyb = ref "\n" (* buffer *)
|
||||
val yybl = ref 1 (*buffer length *)
|
||||
val yybufpos = ref 1 (* location of next character to use *)
|
||||
val yygone = ref 1 (* position in file of beginning of buffer *)
|
||||
val yydone = ref false (* eof found yet? *)
|
||||
val yybegin = ref 1 (*Current 'start state' for lexer *)
|
||||
|
||||
val YYBEGIN = fn (Internal.StartStates.STARTSTATE x) =>
|
||||
yybegin := x
|
||||
|
||||
fun lex () : Internal.result =
|
||||
let fun continue() = lex() in
|
||||
let fun scan (s,AcceptingLeaves : Internal.yyfinstate list list,l,i0) =
|
||||
let fun action (i,nil) = raise LexError
|
||||
| action (i,nil::l) = action (i-1,l)
|
||||
| action (i,(node::acts)::l) =
|
||||
case node of
|
||||
Internal.N yyk =>
|
||||
(let val yytext = substring(!yyb,i0,i-i0)
|
||||
val yypos = i0+ !yygone
|
||||
open UserDeclarations Internal.StartStates
|
||||
in (yybufpos := i; case yyk of
|
||||
|
||||
(* Application actions *)
|
||||
|
||||
10 => (Tokens.RBRACE(yypos,yypos+1))
|
||||
| 101 => (Tokens.VAR(yypos,yypos+3))
|
||||
| 106 => (Tokens.TYPE(yypos,yypos+4))
|
||||
| 112 => (Tokens.ARRAY(yypos,yypos+5))
|
||||
| 115 => (Tokens.IF(yypos,yypos+2))
|
||||
| 12 => (Tokens.LBRACK(yypos,yypos+1))
|
||||
| 120 => (Tokens.THEN(yypos,yypos+4))
|
||||
| 125 => (Tokens.ELSE(yypos,yypos+4))
|
||||
| 128 => (Tokens.DO(yypos,yypos+2))
|
||||
| 131 => (Tokens.OF(yypos,yypos+2))
|
||||
| 134 => (Tokens.ID(yytext,yypos,yypos+size yytext))
|
||||
| 137 => (Tokens.INT(makeInt yytext
|
||||
handle Overflow => (err (yypos,yypos+size yytext)
|
||||
"integer too large";
|
||||
1),
|
||||
yypos,yypos+size yytext))
|
||||
| 139 => (charlist := nil; stringstart := yypos;
|
||||
YYBEGIN S; continue())
|
||||
| 14 => (Tokens.RBRACK(yypos,yypos+1))
|
||||
| 142 => (YYBEGIN A; stringstart := yypos; comLevel := 1; continue())
|
||||
| 145 => (err (yypos,yypos+1) "unmatched close comment";
|
||||
continue())
|
||||
| 147 => (err (yypos,yypos) "non-Ascii character";
|
||||
continue())
|
||||
| 149 => (err (yypos,yypos) "illegal token";
|
||||
continue())
|
||||
| 152 => (inc comLevel; continue())
|
||||
| 154 => (inc lineNum; linePos := yypos :: !linePos; continue())
|
||||
| 157 => (dec comLevel; if !comLevel=0 then YYBEGIN INITIAL else (); continue())
|
||||
| 159 => (continue())
|
||||
| 16 => (Tokens.COLON(yypos,yypos+1))
|
||||
| 161 => (YYBEGIN INITIAL; Tokens.STRING(makeString(),
|
||||
!stringstart,yypos+1))
|
||||
| 163 => (err (!stringstart,yypos) "unclosed string";
|
||||
inc lineNum; linePos := yypos :: !linePos;
|
||||
YYBEGIN INITIAL; Tokens.STRING(makeString(),!stringstart,yypos))
|
||||
| 166 => (inc lineNum; linePos := yypos :: !linePos;
|
||||
YYBEGIN F; continue())
|
||||
| 169 => (YYBEGIN F; continue())
|
||||
| 171 => (inc lineNum; linePos := yypos :: !linePos; continue())
|
||||
| 174 => (continue())
|
||||
| 176 => (YYBEGIN S; stringstart := yypos; continue())
|
||||
| 178 => (err (!stringstart,yypos) "unclosed string";
|
||||
YYBEGIN INITIAL; Tokens.STRING(makeString(),!stringstart,yypos+1))
|
||||
| 18 => (Tokens.SEMICOLON(yypos,yypos+1))
|
||||
| 181 => (addString #"\t"; continue())
|
||||
| 184 => (addString #"\n"; continue())
|
||||
| 187 => (addString #"\\"; continue())
|
||||
| 190 => (addString #"\""; continue())
|
||||
| 194 => (addString(chr(ord(String.sub(yytext,2))-ord(#"@")));
|
||||
continue())
|
||||
| 199 => (let val x = ord(String.sub(yytext,1))*100
|
||||
+ord(String.sub(yytext,2))*10
|
||||
+ord(String.sub(yytext,3))
|
||||
-(ord #"0" * 111)
|
||||
in (if x>255
|
||||
then err (yypos,yypos+4) "illegal ascii escape"
|
||||
else addString(chr x);
|
||||
continue())
|
||||
end)
|
||||
| 2 => (continue())
|
||||
| 20 => (Tokens.LPAREN(yypos,yypos+1))
|
||||
| 201 => (err (yypos,yypos+1) "illegal string escape";
|
||||
continue())
|
||||
| 203 => (addString(String.sub(yytext,0)); continue())
|
||||
| 22 => (Tokens.RPAREN(yypos,yypos+1))
|
||||
| 24 => (Tokens.DOT(yypos,yypos+1))
|
||||
| 26 => (Tokens.PLUS(yypos,yypos+1))
|
||||
| 28 => (Tokens.MINUS(yypos,yypos+1))
|
||||
| 30 => (Tokens.TIMES(yypos,yypos+1))
|
||||
| 32 => (Tokens.DIVIDE(yypos,yypos+1))
|
||||
| 34 => (Tokens.AND(yypos,yypos+1))
|
||||
| 36 => (Tokens.OR(yypos,yypos+1))
|
||||
| 39 => (Tokens.ASSIGN(yypos,yypos+2))
|
||||
| 4 => (inc lineNum; linePos := yypos :: !linePos; continue())
|
||||
| 41 => (Tokens.EQ(yypos,yypos+1))
|
||||
| 44 => (Tokens.NEQ(yypos,yypos+2))
|
||||
| 46 => (Tokens.GT(yypos,yypos+1))
|
||||
| 48 => (Tokens.LT(yypos,yypos+1))
|
||||
| 51 => (Tokens.GE(yypos,yypos+2))
|
||||
| 54 => (Tokens.LE(yypos,yypos+2))
|
||||
| 58 => (Tokens.FOR(yypos,yypos+3))
|
||||
| 6 => (Tokens.COMMA(yypos,yypos+1))
|
||||
| 64 => (Tokens.WHILE(yypos,yypos+5))
|
||||
| 70 => (Tokens.WHILE(yypos,yypos+5))
|
||||
| 74 => (Tokens.LET(yypos,yypos+3))
|
||||
| 77 => (Tokens.IN(yypos,yypos+2))
|
||||
| 8 => (Tokens.LBRACE(yypos,yypos+1))
|
||||
| 81 => (Tokens.NIL(yypos,yypos+3))
|
||||
| 84 => (Tokens.TO(yypos,yypos+2))
|
||||
| 88 => (Tokens.END(yypos,yypos+3))
|
||||
| 97 => (Tokens.FUNCTION(yypos,yypos+8))
|
||||
| _ => raise Internal.LexerError
|
||||
|
||||
) end )
|
||||
|
||||
val {fin,trans} = Vector.sub(Internal.tab, s)
|
||||
val NewAcceptingLeaves = fin::AcceptingLeaves
|
||||
in if l = !yybl then
|
||||
if trans = #trans(Vector.sub(Internal.tab,0))
|
||||
then action(l,NewAcceptingLeaves
|
||||
) else let val newchars= if !yydone then "" else yyinput 1024
|
||||
in if (size newchars)=0
|
||||
then (yydone := true;
|
||||
if (l=i0) then UserDeclarations.eof ()
|
||||
else action(l,NewAcceptingLeaves))
|
||||
else (if i0=l then yyb := newchars
|
||||
else yyb := substring(!yyb,i0,l-i0)^newchars;
|
||||
yygone := !yygone+i0;
|
||||
yybl := size (!yyb);
|
||||
scan (s,AcceptingLeaves,l-i0,0))
|
||||
end
|
||||
else let val NewChar = Char.ord(String.sub(!yyb,l))
|
||||
val NewState = if NewChar<128 then Char.ord(String.sub(trans,NewChar)) else Char.ord(String.sub(trans,128))
|
||||
in if NewState=0 then action(l,NewAcceptingLeaves)
|
||||
else scan(NewState,NewAcceptingLeaves,l+1,i0)
|
||||
end
|
||||
end
|
||||
(*
|
||||
val start= if substring(!yyb,!yybufpos-1,1)="\n"
|
||||
then !yybegin+1 else !yybegin
|
||||
*)
|
||||
in scan(!yybegin (* start *),nil,!yybufpos,!yybufpos)
|
||||
end
|
||||
end
|
||||
in lex
|
||||
end
|
||||
end
|
||||
52
tiger/chap4/absyn.sml
Normal file
52
tiger/chap4/absyn.sml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
structure Absyn =
|
||||
struct
|
||||
|
||||
type pos = int and symbol = Symbol.symbol
|
||||
|
||||
datatype var = SimpleVar of symbol * pos
|
||||
| FieldVar of var * symbol * pos
|
||||
| SubscriptVar of var * exp * pos
|
||||
|
||||
and exp = VarExp of var
|
||||
| NilExp
|
||||
| IntExp of int
|
||||
| StringExp of string * pos
|
||||
| CallExp of {func: symbol, args: exp list, pos: pos}
|
||||
| OpExp of {left: exp, oper: oper, right: exp, pos: pos}
|
||||
| RecordExp of {fields: (symbol * exp * pos) list,
|
||||
typ: symbol, pos: pos}
|
||||
| SeqExp of (exp * pos) list
|
||||
| AssignExp of {var: var, exp: exp, pos: pos}
|
||||
| IfExp of {test: exp, then': exp, else': exp option, pos: pos}
|
||||
| WhileExp of {test: exp, body: exp, pos: pos}
|
||||
| ForExp of {var: symbol, escape: bool ref,
|
||||
lo: exp, hi: exp, body: exp, pos: pos}
|
||||
| BreakExp of pos
|
||||
| LetExp of {decs: dec list, body: exp, pos: pos}
|
||||
| ArrayExp of {typ: symbol, size: exp, init: exp, pos: pos}
|
||||
|
||||
and dec = FunctionDec of fundec list
|
||||
| VarDec of {name: symbol,
|
||||
escape: bool ref,
|
||||
typ: (symbol * pos) option,
|
||||
init: exp,
|
||||
pos: pos}
|
||||
| TypeDec of {name: symbol, ty: ty, pos: pos} list
|
||||
|
||||
and ty = NameTy of symbol * pos
|
||||
| RecordTy of field list
|
||||
| ArrayTy of symbol * pos
|
||||
|
||||
and oper = PlusOp | MinusOp | TimesOp | DivideOp
|
||||
| EqOp | NeqOp | LtOp | LeOp | GtOp | GeOp
|
||||
|
||||
withtype field = {name: symbol, escape: bool ref,
|
||||
typ: symbol, pos: pos}
|
||||
and fundec = {name: symbol,
|
||||
params: field list,
|
||||
result: (symbol * pos) option,
|
||||
body: exp,
|
||||
pos: pos}
|
||||
|
||||
end
|
||||
|
||||
53
tiger/chap4/errormsg.sml
Normal file
53
tiger/chap4/errormsg.sml
Normal file
|
|
@ -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 *)
|
||||
|
||||
22
tiger/chap4/parse.sml
Normal file
22
tiger/chap4/parse.sml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
structure Parse : sig val parse : string -> Absyn.exp end =
|
||||
struct
|
||||
structure TigerLrVals = TigerLrValsFun(structure Token = LrParser.Token)
|
||||
structure Lex = TigerLexFun(structure Tokens = TigerLrVals.Tokens)
|
||||
structure TigerP = Join(structure ParserData = TigerLrVals.ParserData
|
||||
structure Lex=Lex
|
||||
structure LrParser = LrParser)
|
||||
fun parse filename =
|
||||
let val _ = (ErrorMsg.reset(); ErrorMsg.fileName := filename)
|
||||
val file = TextIO.openIn filename
|
||||
fun get _ = TextIO.input file
|
||||
fun parseerror(s,p1,p2) = ErrorMsg.error p1 s
|
||||
val lexer = LrParser.Stream.streamify (Lex.makeLexer get)
|
||||
val (absyn, _) = TigerP.parse(30,lexer,parseerror,())
|
||||
in TextIO.closeIn file;
|
||||
absyn
|
||||
end handle LrParser.ParseError => raise ErrorMsg.Error
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
128
tiger/chap4/prabsyn.sml
Normal file
128
tiger/chap4/prabsyn.sml
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
structure PrintAbsyn :
|
||||
sig val print : TextIO.outstream * Absyn.exp -> unit end =
|
||||
struct
|
||||
|
||||
structure A = Absyn
|
||||
|
||||
fun print (outstream, e0) =
|
||||
let fun say s = TextIO.output(outstream,s)
|
||||
fun sayln s= (say s; say "\n")
|
||||
|
||||
fun indent 0 = ()
|
||||
| indent i = (say " "; indent(i-1))
|
||||
|
||||
fun opname A.PlusOp = "PlusOp"
|
||||
| opname A.MinusOp = "MinusOp"
|
||||
| opname A.TimesOp = "TimesOp"
|
||||
| opname A.DivideOp = "DivideOp"
|
||||
| opname A.EqOp = "EqOp"
|
||||
| opname A.NeqOp = "NeqOp"
|
||||
| opname A.LtOp = "LtOp"
|
||||
| opname A.LeOp = "LeOp"
|
||||
| opname A.GtOp = "GtOp"
|
||||
| opname A.GeOp = "GeOp"
|
||||
|
||||
fun dolist d f [a] = (sayln ""; f(a,d+1))
|
||||
| dolist d f (a::r) = (sayln ""; f(a,d+1); say ","; dolist d f r)
|
||||
| dolist d f nil = ()
|
||||
|
||||
|
||||
fun var(A.SimpleVar(s,p),d) = (indent d; say "SimpleVar(";
|
||||
say(Symbol.name s); say ")")
|
||||
| var(A.FieldVar(v,s,p),d) = (indent d; sayln "FieldVar(";
|
||||
var(v,d+1); sayln ",";
|
||||
indent(d+1); say(Symbol.name s); say ")")
|
||||
| var(A.SubscriptVar(v,e,p),d) = (indent d; sayln "SubscriptVar(";
|
||||
var(v,d+1); sayln ",";
|
||||
exp(e,d+1); say ")")
|
||||
and exp(A.VarExp v, d) = (indent d; sayln "VarExp("; var(v,d+1); say ")")
|
||||
| exp(A.NilExp, d) = (indent d; say "NilExp")
|
||||
| exp(A.IntExp i, d) = (indent d; say "IntExp("; say(Int.toString i);
|
||||
say ")")
|
||||
| exp(A.StringExp(s,p),d) = (indent d; say "StringExp(\"";
|
||||
say s; say "\")")
|
||||
| exp(A.CallExp{func,args,pos},d) =
|
||||
(indent d; say "CallExp("; say(Symbol.name func);
|
||||
say ",["; dolist d exp args; say "])")
|
||||
| exp(A.OpExp{left,oper,right,pos},d) =
|
||||
(indent d; say "OpExp("; say(opname oper); sayln ",";
|
||||
exp(left,d+1); sayln ","; exp(right,d+1); say ")")
|
||||
| exp(A.RecordExp{fields,typ,pos},d) =
|
||||
let fun f((name,e,pos),d) =
|
||||
(indent d; say "("; say(Symbol.name name);
|
||||
sayln ","; exp(e,d+1);
|
||||
say ")")
|
||||
in indent d; say "RecordExp("; say(Symbol.name typ);
|
||||
sayln ",["; dolist d f fields; say "])"
|
||||
end
|
||||
| exp(A.SeqExp l, d) = (indent d; say "SeqExp["; dolist d exp (map #1 l);
|
||||
say "]")
|
||||
| exp(A.AssignExp{var=v,exp=e,pos},d) =
|
||||
(indent d; sayln "AssignExp("; var(v,d+1); sayln ",";
|
||||
exp(e,d+1); say ")")
|
||||
| exp(A.IfExp{test,then',else',pos},d) =
|
||||
(indent d; sayln "IfExp("; exp(test,d+1); sayln ",";
|
||||
exp(then',d+1);
|
||||
case else' of NONE => ()
|
||||
| SOME e => (sayln ","; exp(e,d+1));
|
||||
say ")")
|
||||
| exp(A.WhileExp{test,body,pos},d) =
|
||||
(indent d; sayln "WhileExp("; exp(test,d+1); sayln ",";
|
||||
exp(body,d+1); say ")")
|
||||
| exp(A.ForExp{var=v,escape=b,lo,hi,body,pos},d) =
|
||||
(indent d; sayln "ForExp(";
|
||||
say(Symbol.name v); say ","; say(Bool.toString (!b)); sayln ",";
|
||||
exp(lo,d+1); sayln ","; exp(hi,d+1); sayln ",";
|
||||
exp(body,d+1); say ")")
|
||||
| exp(A.BreakExp p, d) = (indent d; say "BreakExp")
|
||||
| exp(A.LetExp{decs,body,pos},d) =
|
||||
(indent d; say "LetExp([";
|
||||
dolist d dec decs; sayln "],"; exp(body,d+1); say")")
|
||||
| exp(A.ArrayExp{typ,size,init,pos},d) =
|
||||
(indent d; say "ArrayExp("; say(Symbol.name typ); sayln ",";
|
||||
exp(size,d+1); sayln ","; exp(init,d+1); say ")")
|
||||
|
||||
|
||||
and dec(A.FunctionDec l, d) =
|
||||
let fun field({name,escape,typ,pos},d) =
|
||||
(indent d; say "("; say(Symbol.name name);
|
||||
say ","; say(Bool.toString(!escape));
|
||||
say ","; say(Symbol.name typ); say ")")
|
||||
fun f({name,params,result,body,pos},d) =
|
||||
(indent d; say "("; say (Symbol.name name); say ",[";
|
||||
dolist d field params; sayln "],";
|
||||
case result of NONE => say "NONE"
|
||||
| SOME(s,_) => (say "SOME("; say(Symbol.name s); say ")");
|
||||
sayln ","; exp(body,d+1); say ")")
|
||||
in indent d; say "FunctionDec["; dolist d f l; say "]"
|
||||
end
|
||||
| dec(A.VarDec{name,escape,typ,init,pos},d) =
|
||||
(indent d; say "VarDec("; say(Symbol.name name); say ",";
|
||||
say(Bool.toString (!escape)); say ",";
|
||||
case typ of NONE => say "NONE"
|
||||
| SOME(s,p)=> (say "SOME("; say(Symbol.name s); say ")");
|
||||
sayln ","; exp(init,d+1); say ")")
|
||||
| dec(A.TypeDec l, d) =
|
||||
let fun tdec({name,ty=t,pos},d) = (indent d; say"(";
|
||||
say(Symbol.name name); sayln ",";
|
||||
ty(t,d+1); say ")")
|
||||
in indent d; say "TypeDec["; dolist d tdec l; say "]"
|
||||
end
|
||||
|
||||
and ty(A.NameTy(s,p), d) = (indent d; say "NameTy("; say(Symbol.name s);
|
||||
say ")")
|
||||
| ty(A.RecordTy l, d) =
|
||||
let fun f({name,escape,typ,pos},d) =
|
||||
(indent d; say "("; say (Symbol.name name);
|
||||
say ","; say (Bool.toString (!escape)); say ",";
|
||||
say (Symbol.name typ); say ")")
|
||||
in indent d; say "RecordTy["; dolist d f l; say "]"
|
||||
end
|
||||
| ty(A.ArrayTy(s,p),d) = (indent d; say "ArrayTy("; say(Symbol.name s);
|
||||
say ")")
|
||||
|
||||
in exp(e0,0); sayln ""; TextIO.flushOut outstream
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
13
tiger/chap4/sources.cm
Normal file
13
tiger/chap4/sources.cm
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Group is
|
||||
|
||||
absyn.sml
|
||||
errormsg.sml
|
||||
table.sig
|
||||
table.sml
|
||||
symbol.sml
|
||||
parse.sml
|
||||
tiger.lex
|
||||
tiger.grm
|
||||
smlnj-lib.cm
|
||||
ml-yacc-lib.cm
|
||||
|
||||
43
tiger/chap4/symbol.sml
Normal file
43
tiger/chap4/symbol.sml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
signature SYMBOL =
|
||||
sig
|
||||
eqtype symbol
|
||||
val symbol : string -> symbol
|
||||
val name : symbol -> string
|
||||
type 'a table
|
||||
val empty : 'a table
|
||||
val enter : 'a table * symbol * 'a -> 'a table
|
||||
val look : 'a table * symbol -> 'a option
|
||||
end
|
||||
|
||||
structure Symbol :> SYMBOL =
|
||||
struct
|
||||
|
||||
type symbol = string * int
|
||||
|
||||
structure H = HashTable
|
||||
|
||||
exception Symbol
|
||||
val nextsym = ref 0
|
||||
val sizeHint = 128
|
||||
val hashtable : (string,int) H.hash_table =
|
||||
H.mkTable(HashString.hashString, op = ) (sizeHint,Symbol)
|
||||
|
||||
fun symbol name =
|
||||
case H.find hashtable name
|
||||
of SOME i => (name,i)
|
||||
| NONE => let val i = !nextsym
|
||||
in nextsym := i+1;
|
||||
H.insert hashtable (name,i);
|
||||
(name,i)
|
||||
end
|
||||
|
||||
fun name(s,n) = s
|
||||
|
||||
structure Table = IntMapTable(type key = symbol
|
||||
fun getInt(s,n) = n)
|
||||
|
||||
type 'a table= 'a Table.table
|
||||
val empty = Table.empty
|
||||
val enter = Table.enter
|
||||
val look = Table.look
|
||||
end
|
||||
9
tiger/chap4/table.sig
Normal file
9
tiger/chap4/table.sig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
signature TABLE =
|
||||
sig
|
||||
type key
|
||||
type 'a table
|
||||
val empty : 'a table
|
||||
val enter : 'a table * key * 'a -> 'a table
|
||||
val look : 'a table * key -> 'a option
|
||||
end
|
||||
|
||||
9
tiger/chap4/table.sml
Normal file
9
tiger/chap4/table.sml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
functor IntMapTable (type key
|
||||
val getInt: key -> int) : TABLE =
|
||||
struct
|
||||
type key=key
|
||||
type 'a table = 'a IntBinaryMap.map
|
||||
val empty = IntBinaryMap.empty
|
||||
fun enter(t,k,a) = IntBinaryMap.insert(t,getInt k,a)
|
||||
fun look(t,k) = IntBinaryMap.find(t,getInt k)
|
||||
end
|
||||
40
tiger/chap4/tiger.grm
Normal file
40
tiger/chap4/tiger.grm
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
structure A = Absyn
|
||||
|
||||
%%
|
||||
%term
|
||||
EOF
|
||||
| ID of string
|
||||
| INT of int | STRING of string
|
||||
| COMMA | COLON | SEMICOLON | LPAREN | RPAREN | LBRACK | RBRACK
|
||||
| LBRACE | RBRACE | DOT
|
||||
| PLUS | MINUS | TIMES | DIVIDE | EQ | NEQ | LT | LE | GT | GE
|
||||
| AND | OR | ASSIGN
|
||||
| ARRAY | IF | THEN | ELSE | WHILE | FOR | TO | DO | LET | IN | END | OF
|
||||
| BREAK | NIL
|
||||
| FUNCTION | VAR | TYPE
|
||||
|
||||
%nonterm exp | program of A.exp
|
||||
|
||||
%pos int
|
||||
%verbose
|
||||
%start program
|
||||
%eop EOF
|
||||
%noshift EOF
|
||||
|
||||
%name Tiger
|
||||
|
||||
%keyword WHILE FOR TO BREAK LET IN END FUNCTION VAR TYPE ARRAY IF THEN ELSE
|
||||
DO OF NIL
|
||||
|
||||
%prefer THEN ELSE LPAREN
|
||||
|
||||
%value ID ("bogus")
|
||||
%value INT (1)
|
||||
%value STRING ("")
|
||||
|
||||
%%
|
||||
|
||||
program : exp (exp)
|
||||
|
||||
|
||||
exp: NIL (A.NilExp)
|
||||
16
tiger/chap5/types.sml
Normal file
16
tiger/chap5/types.sml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
structure Types =
|
||||
struct
|
||||
|
||||
type unique = unit ref
|
||||
|
||||
datatype ty =
|
||||
RECORD of (Symbol.symbol * ty) list * unique
|
||||
| NIL
|
||||
| INT
|
||||
| STRING
|
||||
| ARRAY of ty * unique
|
||||
| NAME of Symbol.symbol * ty option ref
|
||||
| UNIT
|
||||
|
||||
end
|
||||
|
||||
64
tiger/chap7/printtree.sml
Normal file
64
tiger/chap7/printtree.sml
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
structure Printtree :
|
||||
sig val printtree : TextIO.outstream * Tree.stm -> unit end =
|
||||
struct
|
||||
|
||||
structure T = Tree
|
||||
fun printtree (outstream, s0) =
|
||||
let fun say s = TextIO.output(outstream,s)
|
||||
fun sayln s= (say s; say "\n")
|
||||
|
||||
fun indent 0 = ()
|
||||
| indent i = (say " "; indent(i-1))
|
||||
|
||||
fun stm(T.SEQ(a,b),d) =
|
||||
(indent d; sayln "SEQ("; stm(a,d+1); sayln ","; stm(b,d+1); say ")")
|
||||
| stm(T.LABEL lab, d) = (indent d; say "LABEL "; say (Symbol.name lab))
|
||||
| stm(T.JUMP (e,_), d) = (indent d; sayln "JUMP("; exp(e,d+1); say ")")
|
||||
| stm(T.CJUMP(r,a,b,t,f),d) = (indent d; say "CJUMP(";
|
||||
relop r; sayln ",";
|
||||
exp(a,d+1); sayln ","; exp(b,d+1); sayln ",";
|
||||
indent(d+1); say(Symbol.name t);
|
||||
say ","; say (Symbol.name f); say ")")
|
||||
| stm(T.MOVE(a,b),d) = (indent d; sayln "MOVE("; exp(a,d+1); sayln ",";
|
||||
exp(b,d+1); say ")")
|
||||
| stm(T.EXP e, d) = (indent d; sayln "EXP("; exp(e,d+1); say ")")
|
||||
|
||||
and exp(T.BINOP(p,a,b),d) = (indent d; say "BINOP("; binop p; sayln ",";
|
||||
exp(a,d+1); sayln ","; exp(b,d+1); say ")")
|
||||
| exp(T.MEM(e),d) = (indent d; sayln "MEM("; exp(e,d+1); say ")")
|
||||
| exp(T.TEMP t, d) = (indent d; say "TEMP t"; say(Int.toString t))
|
||||
| exp(T.ESEQ(s,e),d) = (indent d; sayln "ESEQ("; stm(s,d+1); sayln ",";
|
||||
exp(e,d+1); say ")")
|
||||
| exp(T.NAME lab, d) = (indent d; say "NAME "; say (Symbol.name lab))
|
||||
| exp(T.CONST i, d) = (indent d; say "CONST "; say(Int.toString i))
|
||||
| exp(T.CALL(e,el),d) = (indent d; sayln "CALL("; exp(e,d+1);
|
||||
app (fn a => (sayln ","; exp(a,d+2))) el;
|
||||
say ")")
|
||||
|
||||
and binop T.PLUS = say "PLUS"
|
||||
| binop T.MINUS = say "MINUS"
|
||||
| binop T.MUL = say "MUL"
|
||||
| binop T.DIV = say "DIV"
|
||||
| binop T.AND = say "AND"
|
||||
| binop T.OR = say "OR"
|
||||
| binop T.LSHIFT = say "LSHIFT"
|
||||
| binop T.RSHIFT = say "RSHIFT"
|
||||
| binop T.ARSHIFT = say "ARSHIFT"
|
||||
| binop T.XOR = say "XOR"
|
||||
|
||||
and relop T.EQ = say "EQ"
|
||||
| relop T.NE = say "NE"
|
||||
| relop T.LT = say "LT"
|
||||
| relop T.GT = say "GT"
|
||||
| relop T.LE = say "LE"
|
||||
| relop T.GE = say "GE"
|
||||
| relop T.ULT = say "ULT"
|
||||
| relop T.ULE = say "ULE"
|
||||
| relop T.UGT = say "UGT"
|
||||
| relop T.UGE = say "UGE"
|
||||
|
||||
in stm(s0,0); sayln ""; TextIO.flushOut outstream
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
11
tiger/chap7/temp.sig
Normal file
11
tiger/chap7/temp.sig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
signature TEMP =
|
||||
sig
|
||||
eqtype temp
|
||||
val newtemp : unit -> temp
|
||||
structure Table : TABLE sharing type Table.key = temp
|
||||
val makestring: temp -> string
|
||||
type label = Symbol.symbol
|
||||
val newlabel : unit -> label
|
||||
val namedlabel : string -> label
|
||||
end
|
||||
|
||||
24
tiger/chap7/temp.sml
Normal file
24
tiger/chap7/temp.sml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
(* make this an abstraction sometime *)
|
||||
structure Temp : TEMP =
|
||||
struct
|
||||
type temp = int
|
||||
val temps = ref 100
|
||||
fun newtemp() = let val t = !temps in temps := t+1; t end
|
||||
|
||||
structure Table = IntMapTable(type key = int
|
||||
fun getInt n = n)
|
||||
|
||||
fun makestring t = "t" ^ Int.toString t
|
||||
|
||||
type label = Symbol.symbol
|
||||
|
||||
local structure F = Format
|
||||
fun postinc x = let val i = !x in x := i+1; i end
|
||||
val labs = ref 0
|
||||
in
|
||||
fun newlabel() = Symbol.symbol(F.format "L%d" [F.INT(postinc labs)])
|
||||
val namedlabel = Symbol.symbol
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
58
tiger/chap7/tree.sml
Normal file
58
tiger/chap7/tree.sml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
signature TREE =
|
||||
sig
|
||||
type label = Temp.label
|
||||
type size
|
||||
|
||||
datatype stm = SEQ of stm * stm
|
||||
| LABEL of label
|
||||
| JUMP of exp * label list
|
||||
| CJUMP of relop * exp * exp * label * label
|
||||
| MOVE of exp * exp
|
||||
| EXP of exp
|
||||
|
||||
and exp = BINOP of binop * exp * exp
|
||||
| MEM of exp
|
||||
| TEMP of Temp.temp
|
||||
| ESEQ of stm * exp
|
||||
| NAME of label
|
||||
| CONST of int
|
||||
| CALL of exp * exp list
|
||||
|
||||
and binop = PLUS | MINUS | MUL | DIV
|
||||
| AND | OR | LSHIFT | RSHIFT | ARSHIFT | XOR
|
||||
|
||||
and relop = EQ | NE | LT | GT | LE | GE
|
||||
| ULT | ULE | UGT | UGE
|
||||
|
||||
val notRel : relop -> relop
|
||||
val commute: relop -> relop
|
||||
end
|
||||
|
||||
structure Tree : TREE =
|
||||
struct
|
||||
type label=Temp.label
|
||||
type size = int
|
||||
|
||||
datatype stm = SEQ of stm * stm
|
||||
| LABEL of label
|
||||
| JUMP of exp * label list
|
||||
| CJUMP of relop * exp * exp * label * label
|
||||
| MOVE of exp * exp
|
||||
| EXP of exp
|
||||
|
||||
and exp = BINOP of binop * exp * exp
|
||||
| MEM of exp
|
||||
| TEMP of Temp.temp
|
||||
| ESEQ of stm * exp
|
||||
| NAME of label
|
||||
| CONST of int
|
||||
| CALL of exp * exp list
|
||||
|
||||
and binop = PLUS | MINUS | MUL | DIV
|
||||
| AND | OR | LSHIFT | RSHIFT | ARSHIFT | XOR
|
||||
|
||||
and relop = EQ | NE | LT | GT | LE | GE
|
||||
| ULT | ULE | UGT | UGE
|
||||
|
||||
end
|
||||
|
||||
183
tiger/chap8/canon.sml
Normal file
183
tiger/chap8/canon.sml
Normal file
|
|
@ -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
|
||||
39
tiger/chap9/assem.sml
Normal file
39
tiger/chap9/assem.sml
Normal file
|
|
@ -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
|
||||
|
||||
183
tiger/chap9/canon.sml
Normal file
183
tiger/chap9/canon.sml
Normal file
|
|
@ -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
|
||||
23
tiger/chap9/flowgraph.sml
Normal file
23
tiger/chap9/flowgraph.sml
Normal file
|
|
@ -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
|
||||
23
tiger/chap9/graph.sig
Normal file
23
tiger/chap9/graph.sig
Normal file
|
|
@ -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
|
||||
80
tiger/chap9/graph.sml
Normal file
80
tiger/chap9/graph.sml
Normal file
|
|
@ -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
|
||||
|
||||
39
tiger/chap9/main.sml
Normal file
39
tiger/chap9/main.sml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
structure Main = struct
|
||||
|
||||
structure Tr = Translate
|
||||
structure F = Frame
|
||||
structure R = RegAlloc
|
||||
|
||||
fun getsome (SOME x) = x
|
||||
|
||||
fun emitproc out (F.PROC{body,frame}) =
|
||||
let val _ = print ("emit " ^ Frame.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 (Mips.codegen frame) stms')
|
||||
val format0 = Assem.format(Temp.makestring)
|
||||
in app (fn i => TextIO.output(out,format0 i)) instrs;
|
||||
end
|
||||
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
|
||||
|
||||
fun compile filename =
|
||||
let val absyn = Parse.parse filename
|
||||
val frags = (FindEscape.prog absyn; Semant.transProg absyn)
|
||||
in
|
||||
withOpenFile (filename ^ ".s")
|
||||
(fn out => (app (emitproc out) frags))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
109
tiger/chap9/runtime.c
Normal file
109
tiger/chap9/runtime.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
56
tiger/testcases/merge.tig
Normal file
56
tiger/testcases/merge.tig
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
let
|
||||
|
||||
type any = {any : int}
|
||||
var buffer := getchar()
|
||||
|
||||
function readint(any: any) : int =
|
||||
let var i := 0
|
||||
function isdigit(s : string) : int =
|
||||
ord(buffer)>=ord("0") & ord(buffer)<=ord("9")
|
||||
function skipto() =
|
||||
while buffer=" " | buffer="\n"
|
||||
do buffer := getchar()
|
||||
in skipto();
|
||||
any.any := isdigit(buffer);
|
||||
while isdigit(buffer)
|
||||
do (i := i*10+ord(buffer)-ord("0"); buffer := getchar());
|
||||
i
|
||||
end
|
||||
|
||||
type list = {first: int, rest: list}
|
||||
|
||||
function readlist() : list =
|
||||
let var any := any{any=0}
|
||||
var i := readint(any)
|
||||
in if any.any
|
||||
then list{first=i,rest=readlist()}
|
||||
else nil
|
||||
end
|
||||
|
||||
function merge(a: list, b: list) : list =
|
||||
if a=nil then b
|
||||
else if b=nil then a
|
||||
else if a.first < b.first
|
||||
then list{first=a.first,rest=merge(a.rest,b)}
|
||||
else list{first=b.first,rest=merge(a,b.rest)}
|
||||
|
||||
function printint(i: int) =
|
||||
let function f(i:int) = if i>0
|
||||
then (f(i/10); print(chr(i-i/10*10+ord("0"))))
|
||||
in if i<0 then (print("-"); f(-i))
|
||||
else if i>0 then f(i)
|
||||
else print("0")
|
||||
end
|
||||
|
||||
function printlist(l: list) =
|
||||
if l=nil then print("\n")
|
||||
else (printint(l.first); print(" "); printlist(l.rest))
|
||||
|
||||
var list1 := readlist()
|
||||
var list2 := (buffer:=getchar(); readlist())
|
||||
|
||||
|
||||
/* BODY OF MAIN PROGRAM */
|
||||
in printlist(merge(list1,list2))
|
||||
end
|
||||
|
||||
34
tiger/testcases/queens.tig
Normal file
34
tiger/testcases/queens.tig
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* A program to solve the 8-queens problem */
|
||||
|
||||
let
|
||||
var N := 8
|
||||
|
||||
type intArray = array of int
|
||||
|
||||
var row := intArray [ N ] of 0
|
||||
var col := intArray [ N ] of 0
|
||||
var diag1 := intArray [N+N-1] of 0
|
||||
var diag2 := intArray [N+N-1] of 0
|
||||
|
||||
function printboard() =
|
||||
(for i := 0 to N-1
|
||||
do (for j := 0 to N-1
|
||||
do print(if col[i]=j then " O" else " .");
|
||||
print("\n"));
|
||||
print("\n"))
|
||||
|
||||
function try(c:int) =
|
||||
( /* for i:= 0 to c do print("."); print("\n"); flush();*/
|
||||
if c=N
|
||||
then printboard()
|
||||
else for r := 0 to N-1
|
||||
do if row[r]=0 & diag1[r+c]=0 & diag2[r+7-c]=0
|
||||
then (row[r]:=1; diag1[r+c]:=1; diag2[r+7-c]:=1;
|
||||
col[c]:=r;
|
||||
try(c+1);
|
||||
row[r]:=0; diag1[r+c]:=0; diag2[r+7-c]:=0)
|
||||
|
||||
)
|
||||
in try(0)
|
||||
end
|
||||
|
||||
7
tiger/testcases/test1.tig
Normal file
7
tiger/testcases/test1.tig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* an array type and an array variable */
|
||||
let
|
||||
type arrtype = array of int
|
||||
var arr1:arrtype := arrtype [10] of 0
|
||||
in
|
||||
arr1
|
||||
end
|
||||
2
tiger/testcases/test10.tig
Normal file
2
tiger/testcases/test10.tig
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/* error : body of while not unit */
|
||||
while(10 > 5) do 5+6
|
||||
3
tiger/testcases/test11.tig
Normal file
3
tiger/testcases/test11.tig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/* error hi expr is not int, and index variable erroneously assigned to. */
|
||||
for i:=10 to " " do
|
||||
i := i - 1
|
||||
7
tiger/testcases/test12.tig
Normal file
7
tiger/testcases/test12.tig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* valid for and let */
|
||||
|
||||
let
|
||||
var a:= 0
|
||||
in
|
||||
for i:=0 to 100 do (a:=a+1;())
|
||||
end
|
||||
3
tiger/testcases/test13.tig
Normal file
3
tiger/testcases/test13.tig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/* error: comparison of incompatible types */
|
||||
|
||||
3 > "df"
|
||||
13
tiger/testcases/test14.tig
Normal file
13
tiger/testcases/test14.tig
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* error : compare rec with array */
|
||||
|
||||
let
|
||||
|
||||
type arrtype = array of int
|
||||
type rectype = {name:string, id: int}
|
||||
|
||||
var rec := rectype {name="aname", id=0}
|
||||
var arr := arrtype [3] of 0
|
||||
|
||||
in
|
||||
if rec <> arr then 3 else 4
|
||||
end
|
||||
3
tiger/testcases/test15.tig
Normal file
3
tiger/testcases/test15.tig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/* error : if-then returns non unit */
|
||||
|
||||
if 20 then 3
|
||||
11
tiger/testcases/test16.tig
Normal file
11
tiger/testcases/test16.tig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* error: mutually recursive types thet do not pass through record or array */
|
||||
let
|
||||
|
||||
type a=c
|
||||
type b=a
|
||||
type c=d
|
||||
type d=a
|
||||
|
||||
in
|
||||
""
|
||||
end
|
||||
10
tiger/testcases/test17.tig
Normal file
10
tiger/testcases/test17.tig
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* error: definition of recursive types is interrupted */
|
||||
let
|
||||
/* define a tree */
|
||||
type tree ={key: int, children: treelist}
|
||||
var d:int :=0
|
||||
type treelist = {hd: tree, tl: treelist}
|
||||
|
||||
in
|
||||
d
|
||||
end
|
||||
15
tiger/testcases/test18.tig
Normal file
15
tiger/testcases/test18.tig
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* error : definition of recursive functions is interrupted */
|
||||
let
|
||||
|
||||
function do_nothing1(a: int, b: string):int=
|
||||
(do_nothing2(a+1);0)
|
||||
|
||||
var d:=0
|
||||
|
||||
function do_nothing2(d: int):string =
|
||||
(do_nothing1(d, "str");" ")
|
||||
|
||||
in
|
||||
do_nothing1(0, "str2")
|
||||
end
|
||||
|
||||
13
tiger/testcases/test19.tig
Normal file
13
tiger/testcases/test19.tig
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* error : second function uses variables local to the first one, undeclared variable */
|
||||
let
|
||||
|
||||
function do_nothing1(a: int, b: string):int=
|
||||
(do_nothing2(a+1);0)
|
||||
|
||||
function do_nothing2(d: int):string =
|
||||
(do_nothing1(a, "str");" ")
|
||||
|
||||
in
|
||||
do_nothing1(0, "str2")
|
||||
end
|
||||
|
||||
9
tiger/testcases/test2.tig
Normal file
9
tiger/testcases/test2.tig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* arr1 is valid since expression 0 is int = myint */
|
||||
let
|
||||
type myint = int
|
||||
type arrtype = array of myint
|
||||
|
||||
var arr1:arrtype := arrtype [10] of 0
|
||||
in
|
||||
arr1
|
||||
end
|
||||
3
tiger/testcases/test20.tig
Normal file
3
tiger/testcases/test20.tig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/* error: undeclared variable i */
|
||||
|
||||
while 10 > 5 do (i+1;())
|
||||
13
tiger/testcases/test21.tig
Normal file
13
tiger/testcases/test21.tig
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* error : procedure returns value and procedure is used in arexpr */
|
||||
let
|
||||
|
||||
/* calculate n! */
|
||||
function nfactor(n: int) =
|
||||
if n = 0
|
||||
then 1
|
||||
else n * nfactor(n-1)
|
||||
|
||||
in
|
||||
nfactor(10)
|
||||
end
|
||||
|
||||
8
tiger/testcases/test22.tig
Normal file
8
tiger/testcases/test22.tig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* error : field not in record type */
|
||||
|
||||
let
|
||||
type rectype = {name:string , id:int}
|
||||
var rec1 := rectype {name="Name", id=0}
|
||||
in
|
||||
rec1.nam := "asd"
|
||||
end
|
||||
9
tiger/testcases/test23.tig
Normal file
9
tiger/testcases/test23.tig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* error : type mismatch */
|
||||
|
||||
let
|
||||
type rectype = {name:string , id:int}
|
||||
var rec1 := rectype {name="aname", id=0}
|
||||
in
|
||||
rec1.name := 3;
|
||||
rec1.id := ""
|
||||
end
|
||||
7
tiger/testcases/test24.tig
Normal file
7
tiger/testcases/test24.tig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* error : variable not array */
|
||||
let
|
||||
var d:=0
|
||||
in
|
||||
d[3]
|
||||
end
|
||||
|
||||
7
tiger/testcases/test25.tig
Normal file
7
tiger/testcases/test25.tig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* error : variable not record */
|
||||
let
|
||||
var d:=0
|
||||
in
|
||||
d.f
|
||||
end
|
||||
|
||||
3
tiger/testcases/test26.tig
Normal file
3
tiger/testcases/test26.tig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/* error : integer required */
|
||||
|
||||
3 + "var"
|
||||
8
tiger/testcases/test27.tig
Normal file
8
tiger/testcases/test27.tig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* locals hide globals */
|
||||
let
|
||||
var a:=0
|
||||
|
||||
function g(a:int):int = a
|
||||
in
|
||||
g(2)
|
||||
end
|
||||
10
tiger/testcases/test28.tig
Normal file
10
tiger/testcases/test28.tig
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* error : different record types */
|
||||
|
||||
let
|
||||
type rectype1 = {name:string , id:int}
|
||||
type rectype2 = {name:string , id:int}
|
||||
|
||||
var rec1: rectype1 := rectype2 {name="Name", id=0}
|
||||
in
|
||||
rec1
|
||||
end
|
||||
10
tiger/testcases/test29.tig
Normal file
10
tiger/testcases/test29.tig
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* error : different array types */
|
||||
|
||||
let
|
||||
type arrtype1 = array of int
|
||||
type arrtype2 = array of int
|
||||
|
||||
var arr1: arrtype1 := arrtype2 [10] of 0
|
||||
in
|
||||
arr1
|
||||
end
|
||||
8
tiger/testcases/test3.tig
Normal file
8
tiger/testcases/test3.tig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* a record type and a record variable */
|
||||
let
|
||||
type rectype = {name:string, age:int}
|
||||
var rec1:rectype := rectype {name="Nobody", age=1000}
|
||||
in
|
||||
rec1.name := "Somebody";
|
||||
rec1
|
||||
end
|
||||
10
tiger/testcases/test30.tig
Normal file
10
tiger/testcases/test30.tig
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* synonyms are fine */
|
||||
|
||||
let
|
||||
type a = array of int
|
||||
type b = a
|
||||
|
||||
var arr1:a := b [10] of 0
|
||||
in
|
||||
arr1[2]
|
||||
end
|
||||
6
tiger/testcases/test31.tig
Normal file
6
tiger/testcases/test31.tig
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* error : type constraint and init value differ */
|
||||
let
|
||||
var a:int := " "
|
||||
in
|
||||
a
|
||||
end
|
||||
9
tiger/testcases/test32.tig
Normal file
9
tiger/testcases/test32.tig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* error : initializing exp and array type differ */
|
||||
|
||||
let
|
||||
type arrayty = array of int
|
||||
|
||||
var a := arrayty [10] of " "
|
||||
in
|
||||
0
|
||||
end
|
||||
6
tiger/testcases/test33.tig
Normal file
6
tiger/testcases/test33.tig
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* error : unknown type */
|
||||
let
|
||||
var a:= rectype {}
|
||||
in
|
||||
0
|
||||
end
|
||||
6
tiger/testcases/test34.tig
Normal file
6
tiger/testcases/test34.tig
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* error : formals and actuals have different types */
|
||||
let
|
||||
function g (a:int , b:string):int = a
|
||||
in
|
||||
g("one", "two")
|
||||
end
|
||||
6
tiger/testcases/test35.tig
Normal file
6
tiger/testcases/test35.tig
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* error : formals are more then actuals */
|
||||
let
|
||||
function g (a:int , b:string):int = a
|
||||
in
|
||||
g("one")
|
||||
end
|
||||
6
tiger/testcases/test36.tig
Normal file
6
tiger/testcases/test36.tig
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* error : formals are fewer then actuals */
|
||||
let
|
||||
function g (a:int , b:string):int = a
|
||||
in
|
||||
g(3,"one",5)
|
||||
end
|
||||
8
tiger/testcases/test37.tig
Normal file
8
tiger/testcases/test37.tig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* redeclaration of variable; this is legal, there are two different
|
||||
variables with the same name. The second one hides the first. */
|
||||
let
|
||||
var a := 0
|
||||
var a := " "
|
||||
in
|
||||
0
|
||||
end
|
||||
9
tiger/testcases/test38.tig
Normal file
9
tiger/testcases/test38.tig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* This is illegal, since there are two types with the same name
|
||||
in the same (consecutive) batch of mutually recursive types.
|
||||
See also test47 */
|
||||
let
|
||||
type a = int
|
||||
type a = string
|
||||
in
|
||||
0
|
||||
end
|
||||
9
tiger/testcases/test39.tig
Normal file
9
tiger/testcases/test39.tig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* This is illegal, since there are two functions with the same name
|
||||
in the same (consecutive) batch of mutually recursive functions.
|
||||
See also test48 */
|
||||
let
|
||||
function g(a:int):int = a
|
||||
function g(a:int):int = a
|
||||
in
|
||||
0
|
||||
end
|
||||
13
tiger/testcases/test4.tig
Normal file
13
tiger/testcases/test4.tig
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* define a recursive function */
|
||||
let
|
||||
|
||||
/* calculate n! */
|
||||
function nfactor(n: int): int =
|
||||
if n = 0
|
||||
then 1
|
||||
else n * nfactor(n-1)
|
||||
|
||||
in
|
||||
nfactor(10)
|
||||
end
|
||||
|
||||
7
tiger/testcases/test40.tig
Normal file
7
tiger/testcases/test40.tig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* error : procedure returns value */
|
||||
let
|
||||
function g(a:int) = a
|
||||
in
|
||||
g(2)
|
||||
end
|
||||
|
||||
10
tiger/testcases/test41.tig
Normal file
10
tiger/testcases/test41.tig
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* local types hide global */
|
||||
let
|
||||
type a = int
|
||||
in
|
||||
let
|
||||
type a = string
|
||||
in
|
||||
0
|
||||
end
|
||||
end
|
||||
30
tiger/testcases/test42.tig
Normal file
30
tiger/testcases/test42.tig
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* correct declarations */
|
||||
let
|
||||
|
||||
type arrtype1 = array of int
|
||||
type rectype1 = {name:string, address:string, id: int , age: int}
|
||||
type arrtype2 = array of rectype1
|
||||
type rectype2 = {name : string, dates: arrtype1}
|
||||
|
||||
type arrtype3 = array of string
|
||||
|
||||
var arr1 := arrtype1 [10] of 0
|
||||
var arr2 := arrtype2 [5] of rectype1 {name="aname", address="somewhere", id=0, age=0}
|
||||
var arr3:arrtype3 := arrtype3 [100] of ""
|
||||
|
||||
var rec1 := rectype1 {name="Kapoios", address="Kapou", id=02432, age=44}
|
||||
var rec2 := rectype2 {name="Allos", dates= arrtype1 [3] of 1900}
|
||||
|
||||
in
|
||||
|
||||
arr1[0] := 1;
|
||||
arr1[9] := 3;
|
||||
arr2[3].name := "kati";
|
||||
arr2[1].age := 23;
|
||||
arr3[34] := "sfd";
|
||||
|
||||
rec1.name := "sdf";
|
||||
rec2.dates[0] := 2323;
|
||||
rec2.dates[2] := 2323
|
||||
|
||||
end
|
||||
7
tiger/testcases/test43.tig
Normal file
7
tiger/testcases/test43.tig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* initialize with unit and causing type mismatch in addition */
|
||||
|
||||
let
|
||||
var a := ()
|
||||
in
|
||||
a + 3
|
||||
end
|
||||
11
tiger/testcases/test44.tig
Normal file
11
tiger/testcases/test44.tig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* valid nil initialization and assignment */
|
||||
let
|
||||
|
||||
type rectype = {name:string, id:int}
|
||||
var b:rectype := nil
|
||||
|
||||
in
|
||||
|
||||
b := nil
|
||||
|
||||
end
|
||||
8
tiger/testcases/test45.tig
Normal file
8
tiger/testcases/test45.tig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* error: initializing nil expressions not constrained by record type */
|
||||
let
|
||||
type rectype = {name:string, id:int}
|
||||
|
||||
var a:= nil
|
||||
in
|
||||
a
|
||||
end
|
||||
8
tiger/testcases/test46.tig
Normal file
8
tiger/testcases/test46.tig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* valid rec comparisons */
|
||||
let
|
||||
type rectype = {name:string, id:int}
|
||||
var b:rectype := nil
|
||||
in
|
||||
b = nil;
|
||||
b <> nil
|
||||
end
|
||||
11
tiger/testcases/test47.tig
Normal file
11
tiger/testcases/test47.tig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* This is legal. The second type "a" simply hides the first one.
|
||||
Because of the intervening variable declaration, the two "a" types
|
||||
are not in the same batch of mutually recursive types.
|
||||
See also test38 */
|
||||
let
|
||||
type a = int
|
||||
var b := 4
|
||||
type a = string
|
||||
in
|
||||
0
|
||||
end
|
||||
11
tiger/testcases/test48.tig
Normal file
11
tiger/testcases/test48.tig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* This is legal. The second function "g" simply hides the first one.
|
||||
Because of the intervening variable declaration, the two "g" functions
|
||||
are not in the same batch of mutually recursive functions.
|
||||
See also test39 */
|
||||
let
|
||||
function g(a:int):int = a
|
||||
type t = int
|
||||
function g(a:int):int = a
|
||||
in
|
||||
0
|
||||
end
|
||||
8
tiger/testcases/test49.tig
Normal file
8
tiger/testcases/test49.tig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* error: syntax error, nil should not be preceded by type-id. */
|
||||
let
|
||||
type rectype = {name:string, id:int}
|
||||
|
||||
var a:= rectype nil
|
||||
in
|
||||
a
|
||||
end
|
||||
14
tiger/testcases/test5.tig
Normal file
14
tiger/testcases/test5.tig
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* define valid recursive types */
|
||||
let
|
||||
/* define a list */
|
||||
type intlist = {hd: int, tl: intlist}
|
||||
|
||||
/* define a tree */
|
||||
type tree ={key: int, children: treelist}
|
||||
type treelist = {hd: tree, tl: treelist}
|
||||
|
||||
var lis:intlist := intlist { hd=0, tl= nil }
|
||||
|
||||
in
|
||||
lis
|
||||
end
|
||||
13
tiger/testcases/test6.tig
Normal file
13
tiger/testcases/test6.tig
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* define valid mutually recursive procedures */
|
||||
let
|
||||
|
||||
function do_nothing1(a: int, b: string)=
|
||||
do_nothing2(a+1)
|
||||
|
||||
function do_nothing2(d: int) =
|
||||
do_nothing1(d, "str")
|
||||
|
||||
in
|
||||
do_nothing1(0, "str2")
|
||||
end
|
||||
|
||||
13
tiger/testcases/test7.tig
Normal file
13
tiger/testcases/test7.tig
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* define valid mutually recursive functions */
|
||||
let
|
||||
|
||||
function do_nothing1(a: int, b: string):int=
|
||||
(do_nothing2(a+1);0)
|
||||
|
||||
function do_nothing2(d: int):string =
|
||||
(do_nothing1(d, "str");" ")
|
||||
|
||||
in
|
||||
do_nothing1(0, "str2")
|
||||
end
|
||||
|
||||
2
tiger/testcases/test8.tig
Normal file
2
tiger/testcases/test8.tig
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/* correct if */
|
||||
if (10 > 20) then 30 else 40
|
||||
3
tiger/testcases/test9.tig
Normal file
3
tiger/testcases/test9.tig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/* error : types of then - else differ */
|
||||
|
||||
if (5>4) then 13 else " "
|
||||
Loading…
Add table
Add a link
Reference in a new issue