// MICBIX -- second part of builtins for Micro // last edited August 17, 1978 4:02 PM // Copyright Xerox Corporation 1979 get "micdecl.d" external // defined here for MICBI [ xinsert; xfield; xdefmac; xmemory; xlst; xbuiltin; xcchar; xbittable; xfindbit mement entarg; looktype; checkbtx; valsize ] external [ // O.S. Usc; Zero // MICBI minbi; maxbi ] // Literals manifest [ maxnm = 15 // max memory # maxwidth = 256 // max memory width maxsm = #77777 // max memory size ] // Individual builtins let xinsert(ap,l) be // "Insert" builtin [ let filename = vec(40) bcplpak(filename,ap,l) if inpush(filename) eq false then errx("COULD NOT OPEN FILE @B FOR 'INSERT'",false,ap,l) ] and xfield(ap,l,first,last) be // Field builtin [ if (first ls 0) % (last ls first) % (last gr maxwidth) then [ errx("BAD PARAMETERS FOR 'FIELD'") first = 0 last = 0 ] let ep = entarg(ap,l,fldtype) ep!fsbits = (first lshift 8) + last-first+1 ] and xdefmac(ap, l, dp, ok) be [ let ep = lookup(ap,l) test ep eq 0 ifso ep = putin(dp) ifnot test ep!stype le maxtype ifso if ep!stype ne nultype then ep = redeferr(ep, mactype) ifnot unless ok do errx("MACRO @S REDEFINED",false,ep) if ep ne 0 then ep!mcsp = dp ] and doaddr(ap,l,mem,loc) be // "Address" builtin [ let ep = lookup(ap,l) adef((ep eq 0? putin(nultype), ep),mem,loc) ] and mement(ap,l) = valof // Enter symbol for "memory" [ expand(lv ap) let ep = lookup(ap,l) if ep eq 0 then ep = putin(nultype) resultis ep ] and xmemory(ap,l,mw,ms,epsrc,epsink) be // Memory builtin [ let ep = lookup(ap,l) test ep ne 0 ifso redeferr(ep, memtype) ifnot test (mw ls 0) % (mw gr maxwidth) % (ms ls 0) % (ms gr maxsm) ifso errx("ILLEGAL WIDTH OR SIZE FOR 'MEMORY'",true) ifnot test memno eq maxnm ifso errx("TOO MANY MEMORIES",true) ifnot [ memno = memno + 1 ep = putin(memtype) ep!mswidth = mw ep!mssize = ms ep!msno = memno ep!mssource = epsrc-fstop ep!mssink = epsink-fstop let nw = (mw+15) rshift 4 let ep1 = alloc(nw) ep!msdflt = ep1-fstop Zero(ep1, nw) ep!mslist = LFbinary ep!msltag = 0 ep!mspost = 0 ep!mstagmac = 0 ep1 = alloc(mw) ep!mslfields = ep1-fstop setlfbi(ep, 0, 0) // initialize listing fields wmemdef(ep) ] ] and dofld(ep,ap,l,set) be // "assign" and "preassign" builtin [ let typ, val = nil, nil process(ap,l,fldmode, lv typ, lv val) test typ eq undtype ifso [ test set ifnot errx("FORWARD REFERENCE NOT LEGAL IN 'PREASSIGN'") ifso auref(ep,val) ] ifnot test (typ eq inttype) ifso stfield(ep,val,set) ifnot test (typ eq adrtype) ifso stfield(ep,val!asval,set) ifnot errx("ARG IN FIELD STORE NOT INTEGER OR ADDRESS") ] and xlst(ap,l,val) be // "list" builtin test l eq 0 ifso ltoflag = val eq 0 ifnot [ let mem = looktype(ap,l,memtype) mem!mslist = val ] and xbuiltin(ap,l,no) be // "builtin" builtin test (no ls minbi) % (no gr maxbi) ifso errx("ILLEGAL BUILTIN NUMBER FOR @B",false,ap,l) ifnot [ let ep = lookup(ap, l) if (ep ne 0) & (ep!stype eq bitype) & (ep!bsno eq no) then return // OK to redefine a builtin identically ep = entarg(ap,l,bitype) if ep ne 0 then ep!bsno = no ] and xcchar(ap,l) be // "commentchar" builtin [ cmtchar = (l gr 0? ap!0, -1) ] and xbittable(ep, n) be // "bittable" builtin [ let nw = n rshift 4 + 1 let bp = alloc(nw) Zero(bp, nw) ep!bttab = bp-fstop ep!btsize = n ] and xfindbit(ep, lvStart, num, delta, hop, count) = valof // "findbit" builtin -- changes start, returns true if found [ while count ne 0 do [ let i, n = @lvStart, num while n ne 0 do [ if Usc(i, ep!btsize) ge 0 resultis false // ran off end of memory if getbits(ep!bttab+fstop, i, 1) ne 0 goto outer i, n = i+delta, n-1 ] resultis true outer: @lvStart, count = @lvStart+hop, count-1 ] resultis false // exhausted count ] // Utilities for builtins and entarg(ap, l, typ) = valof // Put the argument in the symbol table with type typ. // Error if already defined. [ let ep = lookup(ap, l) test ep eq 0 ifso ep = putin(typ) ifnot test (ep!stype eq nultype) & (typesizes!(realtype(typ)) le typesizes!nultype) ifso ep!stype = typ ifnot ep = redeferr(ep, typ) resultis ep ] and looktype(ap,l,typ) = valof // look up argument, must be of given type. [ let ep = lookup(ap,l) if (ep eq 0) % (typ eq adrtype? ep!stype ge 0, typ eq mactype? ep!stype le maxtype, ep!stype ne typ) then [ errx("@B is not a @L name", false, ap, l, typenames!(realtype(typ))) ep = 0 ] resultis ep ] and checkbtx(index, ep) = valof // check index in bittable [ test Usc(index, ep!btsize) ls 0 ifso resultis true ifnot [ errx("INDEX @V TOO BIG FOR BITTABLE @S",false,index,ep) resultis false ] ] and adef(ep, mem, val) = valof // Define address tag. [ let typ = ep!stype test (typ ne undtype) & (typ ne nultype) & (typ ne mem-fstop) ifso ep = redeferr(ep, adrtype) ifnot [ if ep-fstop ge ofbot then newdef(ep, true) ep!stype = mem-fstop ep!asval = val mem!msltag = ep-fstop ] resultis ep ] and valsize(ep) = typesizes!(realtype(ep!stype)) and realtype(typ) = (typ ls 0? adrtype, typ gr maxtype? mactype, typ) and redeferr(ep, typ) = valof // Indicate a redefinition error, return 0 [ errx("Attempt to redefine @L @S as @L", false, typenames!(realtype(ep!stype)), ep, typenames!(realtype(typ)) ) resultis 0 ]