diff options
Diffstat (limited to 'appl/cmd/limbo/limbo.m')
| -rw-r--r-- | appl/cmd/limbo/limbo.m | 527 |
1 files changed, 527 insertions, 0 deletions
diff --git a/appl/cmd/limbo/limbo.m b/appl/cmd/limbo/limbo.m new file mode 100644 index 00000000..8c2efce0 --- /dev/null +++ b/appl/cmd/limbo/limbo.m @@ -0,0 +1,527 @@ +include "sys.m"; +include "math.m"; +include "string.m"; +include "bufio.m"; +include "isa.m"; +include "workdir.m"; + +# internal dis ops +IEXC: con MAXDIS; +IEXC0: con (MAXDIS+1); +INOOP: con (MAXDIS+2); + +# temporary +LDT: con 1; + +STemp: con NREG * IBY2WD; +RTemp: con STemp + IBY2WD; +DTemp: con RTemp + IBY2WD; +MaxTemp: con DTemp + IBY2WD; +MaxReg: con 1 << 16; +MaxAlign: con IBY2LG; +StrSize: con 256; +MaxIncPath: con 32; # max directories in include path +MaxScope: con 64; # max nested {} +MaxInclude: con 32; # max nested include "" +ScopeBuiltin, +ScopeNils, +ScopeGlobal: con iota; + +Line: type int; +PosBits: con 10; +PosMask: con (1 << PosBits) - 1; + +Src: adt +{ + start: Line; + stop: Line; +}; + +File: adt +{ + name: string; + abs: int; # absolute line of start of the part of file + off: int; # offset to line in the file + in: int; # absolute line where included + act: string; # name of real file with #line fake file + actoff: int; # offset from fake line to real line + sbl: int; # symbol file number +}; + +Val: adt +{ + idval: ref Sym; + ival: big; + rval: real; +}; + +Tok: adt +{ + src: Src; + v: Val; +}; + +# +# addressing modes +# + Aimm, # immediate + Amp, # global + Ampind, # global indirect + Afp, # activation frame + Afpind, # frame indirect + Apc, # branch + Adesc, # type descriptor immediate + Aoff, # offset in module description table + Anoff, # above encoded as a -ve + Aerr, # error + Anone, # no operand + Aldt, # linkage descriptor table immediate + Aend: con byte iota; + +Addr: adt +{ + reg: int; + offset: int; + decl: cyclic ref Decl; +}; + +Inst: adt +{ + src: Src; + op: int; # could be a byte + pc: int; + reach: byte; # could a control path reach this instruction? + sm: byte; # operand addressing modes + mm: byte; + dm: byte; + s: cyclic Addr; # operands + m: cyclic Addr; + d: cyclic Addr; + branch: cyclic ref Inst; # branch destination + next: cyclic ref Inst; + block: int; # blocks nested inside +}; + +Case: adt +{ + nlab: int; + nsnd: int; + offset: int; # offset in mp + labs: cyclic array of Label; + wild: cyclic ref Node; # if nothing matches + iwild: cyclic ref Inst; +}; + +Label: adt +{ + node: cyclic ref Node; + isptr: int; # true if the labelled alt channel is a pointer + start: cyclic ref Node; # value in range [start, stop) => code + stop: cyclic ref Node; + inst: cyclic ref Inst; +}; + +# +# storage classes +# + Dtype, + Dfn, + Dglobal, + Darg, + Dlocal, + Dconst, + Dfield, + Dtag, # pick tags + Dimport, # imported identifier + Dunbound, # unbound identified + Dundef, + Dwundef, # undefined, but don't whine + + Dend: con iota; + +Decl: adt +{ + src: Src; # where declaration + sym: cyclic ref Sym; # name + store: int; # storage class + nid: byte; # block grouping for locals + inline: byte; # inline function + handler: byte; # fn has exception handler(s) + das: byte; # declared with := + dot: cyclic ref Decl; # parent adt or module + ty: cyclic ref Type; + refs: int; # number of references + offset: int; + tag: int; # union tag + + scope: int; # in which it was declared + next: cyclic ref Decl; # list in same scope, field or argument list, etc. + old: cyclic ref Decl; # declaration of the symbol in enclosing scope + + eimport: cyclic ref Node; # expr from which imported + importid: cyclic ref Decl; # identifier imported + timport: cyclic ref Decl; # stack of identifiers importing a type + + init: cyclic ref Node; # data initialization + tref: int; # 1 => is a tmp; >=2 => tmp in use + cycle: byte; # can create a cycle + cyc: byte; # so labelled in source + cycerr: byte; # delivered an error message for cycle? + implicit: byte; # implicit first argument in an adt? + + iface: cyclic ref Decl; # used external declarations in a module + + locals: cyclic ref Decl; # locals for a function + link: cyclic ref Decl; # pointer to parent function or function argument or local share or parent type dec + pc: cyclic ref Inst; # start of function + # endpc: cyclic ref Inst; # limit of function - unused + +# should be able to move this to Type + desc: ref Desc; # heap descriptor +}; + +Desc: adt +{ + id: int; # dis type identifier + used: int; # actually used in output? + map: array of byte; # byte map of pointers + size: int; # length of the object + nmap: int; # length of good bytes in map + next: cyclic ref Desc; +}; + +Dlist: adt +{ + d: ref Decl; + next: cyclic ref Dlist; +}; + +Except: adt +{ + p1: ref Inst; # first pc covered + p2: ref Inst; # last pc not covered + c: ref Case; # exception case instructions + d: ref Decl; # exception definition if any + zn: ref Node; # list of nodes to zero in handler + desc: ref Desc; # descriptor map for above + ne: int; # number of exceptions (ie not strings) in case + next: cyclic ref Except; +}; + +Sym: adt +{ + token: int; + name: string; + hash: int; + next: cyclic ref Sym; + decl: cyclic ref Decl; + unbound: cyclic ref Decl; # place holder for unbound symbols +}; + +# +# ops for nodes +# + Oadd, + Oaddas, + Oadr, + Oadtdecl, + Oalt, + Oand, + Oandand, + Oandas, + Oarray, + Oas, + Obreak, + Ocall, + Ocase, + Ocast, + Ochan, + Ocomma, + Ocomp, + Ocondecl, + Ocons, + Oconst, + Ocont, + Odas, + Odec, + Odiv, + Odivas, + Odo, + Odot, + Oelem, + Oeq, + Oexcept, + Oexdecl, + Oexit, + Oexp, + Oexpas, + Oexstmt, + Ofielddecl, + Ofnptr, + Ofor, + Ofunc, + Ogeq, + Ogt, + Ohd, + Oif, + Oimport, + Oinc, + Oind, + Oindex, + Oinds, + Oindx, + Oinv, + Ojmp, + Olabel, + Olen, + Oleq, + Oload, + Olsh, + Olshas, + Olt, + Omdot, + Omod, + Omodas, + Omoddecl, + Omul, + Omulas, + Oname, + Oneg, + Oneq, + Onot, + Onothing, + Oor, + Ooras, + Ooror, + Opick, + Opickdecl, + Opredec, + Opreinc, + Oraise, + Orange, + Orcv, + Oref, + Oret, + Orsh, + Orshas, + Oscope, + Oself, + Oseq, + Oslice, + Osnd, + Ospawn, + Osub, + Osubas, + Otagof, + Otl, + Otuple, + Otype, + Otypedecl, + Oused, + Ovardecl, + Ovardecli, + Owild, + Oxor, + Oxoras, + + Oend: con iota + 1; + +# +# moves +# + Mas, + Mcons, + Mhd, + Mtl, + + Mend: con iota; + +# +# addressability +# + Rreg, # v(fp) + Rmreg, # v(mp) + Roff, # $v + Rnoff, # $v encoded as -ve + Rdesc, # $v + Rdescp, # $v + Rconst, # $v + Ralways, # preceeding are always addressable + Radr, # v(v(fp)) + Rmadr, # v(v(mp)) + Rcant, # following are not quite addressable + Rpc, # branch address + Rmpc, # cross module branch address + Rareg, # $v(fp) + Ramreg, # $v(mp) + Raadr, # $v(v(fp)) + Ramadr, # $v(v(mp)) + Rldt, # $v + + Rend: con byte iota; + + +Const: adt +{ + val: big; + rval: real; +}; + +PARENS: con 1; +TEMP: con 2; +FNPTRA: con 4; # argument +FNPTR2: con 8; # 2nd parameter +FNPTRN: con 16; # use -ve offset +FNPTR: con FNPTRA|FNPTR2|FNPTRN; + +Node: adt +{ + src: Src; + op: int; + addable: byte; + flags: byte; + temps: byte; + left: cyclic ref Node; + right: cyclic ref Node; + ty: cyclic ref Type; + decl: cyclic ref Decl; + c: ref Const; # for Oconst +}; + + # + # types visible to limbo + # + Tnone, + Tadt, + Tadtpick, # pick case of an adt + Tarray, + Tbig, # 64 bit int + Tbyte, # 8 bit unsigned int + Tchan, + Treal, + Tfn, + Tint, # 32 bit int + Tlist, + Tmodule, + Tref, + Tstring, + Ttuple, + Texception, + Tfix, + Tpoly, + + # + # internal use types + # + Tainit, # array initializers + Talt, # alt channels + Tany, # type of nil + Tarrow, # unresolved ty->ty types + Tcase, # case labels + Tcasel, # case big labels + Tcasec, # case string labels + Tdot, # unresolved ty.id types + Terror, + Tgoto, # goto labels + Tid, # id with unknown type + Tiface, # module interface + Texcept, # exception handler tables + Tinst, # instantiated adt + + Tend: con iota; + + # + # marks for various phases of verifing types + # + OKbind, # type decls are bound + OKverify, # type looks ok + OKsized, # started figuring size + OKref, # recorded use of type + OKclass, # equivalence class found + OKcyc, # checked for cycles + OKcycsize, # checked for cycles and size + OKmodref: # started checking for a module handle + + con byte 1 << iota; + OKmask: con byte 16rff; + + # + # recursive marks + # + TReq, + TRcom, + TRcyc, + TRvis: + con byte 1 << iota; + +# type flags +FULLARGS: con byte 1; # all hidden args added +INST: con byte 2; # instantiated adt +CYCLIC: con byte 4; # cyclic type +POLY: con byte 8; # polymorphic types inside +NOPOLY: con byte 16; # no polymorphic types inside + +# must put some picks in here +Type: adt +{ + src: Src; + kind: int; + ok: byte; # set when type is verified + varargs: byte; # if a function, ends with vargs? + linkall: byte; # put all iface fns in external linkage? + rec: byte; # in the middle of recursive type + pr: byte; # in the middle of printing a recursive type + cons: byte; # exception constant + flags: byte; + sbl: int; # slot in .sbl adt table + sig: int; # signature for dynamic type check + size: int; # storage required, in bytes + align: int; # alignment in bytes + decl: cyclic ref Decl; + tof: cyclic ref Type; + ids: cyclic ref Decl; + tags: cyclic ref Decl;# tagged fields in an adt + polys: cyclic ref Decl;# polymorphic fields in fn or adt + cse: cyclic ref Case;# case or goto labels + teq: cyclic ref Type;# temporary equiv class for equiv checking + tcom: cyclic ref Type;# temporary equiv class for compat checking + eq: cyclic ref Teq; # real equiv class + eraises: cyclic ref Node; # for Tfn only + val: cyclic ref Node; # for Tfix, Tfn, Tadt only + tlist: cyclic ref Typelist; # for Tinst only + tmap: cyclic ref Tpair; # for Tadt only +}; + +# +# type equivalence classes +# +Teq: adt +{ + id: int; # for signing + ty: cyclic ref Type;# an instance of the class + eq: cyclic ref Teq; # used to link eq sets +}; + +Tattr: adt +{ + isptr: int; + refable: int; + conable: int; + isbig: int; + vis: int; # type visible to users +}; + +Tpair: adt +{ + t1: cyclic ref Type; + t2: cyclic ref Type; + nxt: cyclic ref Tpair; +}; + +Typelist: adt +{ + t: cyclic ref Type; + nxt: cyclic ref Typelist; +}; + +Sother, Sloop, Sscope : con iota; |
