def selector(x): global sym while ((sym == ORS.lbrak) or (sym == ORS.period) or (sym == ORS.arrow) or (sym == ORS.lparen) and (x.type_.form in [ORB.Record, ORB.Pointer])): if sym == ORS.lbrak: while True: sym = ORS.Get() y = ORG.Item() expression(y) if x.type_.form == ORB.Array: CheckInt(y) ORG.Index(x, y) x.type_ = x.type_.base else: ORS.Mark("not an array") if sym != ORS.comma: break Check(ORS.rbrak, "no ]") elif sym == ORS.period: sym = ORS.Get(); if sym == ORS.ident: if x.type_.form == ORB.Pointer: ORG.DeRef(x) x.type_ = x.type_.base if x.type_.form == ORB.Record: obj = ORB.thisfield(x.type_) sym = ORS.Get(); if obj != None: ORG.Field(x, obj) x.type_ = obj.type_ else: ORS.Mark("undef") else: ORS.Mark("not a record") else: ORS.Mark("ident?") elif sym == ORS.arrow: sym = ORS.Get() if x.type_.form == ORB.Pointer: ORG.DeRef(x) x.type_ = x.type_.base else: ORS.Mark("not a pointer") elif (sym == ORS.lparen) and (x.type_.form in [ORB.Record, ORB.Pointer]): # (*type_ guard*) sym = ORS.Get() if sym == ORS.ident: obj = qualident() if obj.class_ == ORB.Typ: TypeTest(x, obj.type_, True) else: ORS.Mark("guard type_ expected") else: ORS.Mark("not an identifier") Check(ORS.rparen, " ) missing")
def qualident(): global sym obj = ORB.thisObj() sym = ORS.Get() if obj == None: ORS.Mark("undef") obj = dummy if (sym == ORS.period) and (obj.class_ == ORB.Mod): sym = ORS.Get() if sym == ORS.ident: obj = ORB.thisimport(obj) sym = ORS.Get() if obj == None: ORS.Mark("undef") obj = dummy else: ORS.Mark("identifier expected") obj = dummy return obj
def qualident(): global sym obj = ORB.thisObj() sym = ORS.Get(); if obj == None: ORS.Mark("undef") obj = dummy if (sym == ORS.period) and (obj.class_ == ORB.Mod): sym = ORS.Get() if sym == ORS.ident: obj = ORB.thisimport(obj) sym = ORS.Get() if obj == None: ORS.Mark("undef") obj = dummy else: ORS.Mark("identifier expected") obj = dummy return obj
def IdentList(class_): global sym # VAR obj: ORB.Object; if sym == ORS.ident: first = ORB.NewObj(''.join(ORS.id_), class_) sym = ORS.Get() first.expo = CheckExport() while sym == ORS.comma: sym = ORS.Get() if sym == ORS.ident: obj = ORB.NewObj(''.join(ORS.id_), class_) sym = ORS.Get() obj.expo = CheckExport() else: ORS.Mark("ident?") if sym == ORS.colon: sym = ORS.Get() else: ORS.Mark(":?") else: first = None return first
def ArrayType(type_): global sym # VAR x: ORG.Item; typ: ORB.Type; len_: LONGINT; typ = ORB.Type() typ.form = ORB.NoTyp if sym == ORS.of: # (*dynamic array*) len_ = -1 else: x = ORG.Item() expression(x) if (x.mode == ORB.Const) and (x.type_.form == ORB.Int) and (x.a >= 0): len_ = x.a else: len_ = 0 ORS.Mark("not a valid length") if sym == ORS.of: sym = ORS.Get() typ.base = Type(typ.base) if (typ.base.form == ORB.Array) and (typ.base.len_ < 0): ORS.Mark("dyn array not allowed") elif sym == ORS.comma: sym = ORS.Get() typ.base = ArrayType(typ.base) else: ORS.Mark("missing OF") typ.base = ORB.intType if len_ >= 0: typ.size = len_ * typ.base.size else: typ.size = 2 * ORG.WordSize # (*array desc*) typ.form = ORB.Array typ.len_ = len_ type_ = typ return type_
def Close(modid, key, nofent): ## VAR obj: ORB.Object; ## i, comsize, nofimps, nofptrs, size: LONGINT; ## name: ORS.Ident; ## F: Files.File; R: Files.Rider; # (*exit code*) if version == 0: Put1(Mov, 0, 0, 0) Put3(BR, 7, 0) # (*RISC-0*) else: Put2(Ldr, LNK, SP, 0) Put1(Add, SP, SP, 4) Put3(BR, 7, LNK) obj = ORB.topScope.next nofimps = 0 comsize = 4 nofptrs = 0 while obj != None: if (obj.class_ == ORB.Mod) and (obj.dsc != ORB.system): nofimps += 1 # (*count imports*) elif ((obj.exno != 0) and (obj.class_ == ORB.Const) and (obj.type_.form == ORB.Proc) and (obj.type_.nofpar == 0) and (obj.type_.base == ORB.noType)): i = len(obj.name) # (*count commands*) ## while obj.name[i] != 0x0: ## i += 1 i = (i + 4) / 4 * 4 comsize += i + 4 elif obj.class_ == ORB.Var: nofptrs += NofPtrs(obj.type_) # (*count pointers*) obj = obj.next size = varsize + strx + comsize + ( pc + nofimps + nofent + nofptrs + 1) * 4 # (*varsize includes type_ descriptors*) name = ORB.MakeFileName(modid, ".rsc") # (*write code file*) R = Files.New(name) ## Files.Set(R, F, 0) Files.WriteString(R, modid) Files.WriteInt(R, key) Files.WriteByte(R, version) Files.WriteInt(R, size) obj = ORB.topScope.next while (obj != None) and (obj.class_ == ORB.Mod): # (*imports*) if obj.dsc != ORB.system: Files.WriteString(R, obj.orgname) # removed cast : (ORB.Module) Files.WriteInt(R, obj.val) obj = obj.next Files.Write(R, 0x0) Files.WriteInt(R, tdx * 4) i = 0 while i < tdx: Files.WriteInt(R, data[i]) i += 1 # (*type_ descriptors*) Files.WriteInt(R, varsize - tdx * 4) # (*data*) Files.WriteInt(R, strx) for i in range(strx): Files.WriteString(R, str_[i]) # (*strings*) Files.WriteInt(R, pc) # (*code len_*) for i in range(pc): Files.WriteInt(R, code[i]) # (*program*) obj = ORB.topScope.next while obj != None: # (*commands*) if ((obj.exno != 0) and (obj.class_ == ORB.Const) and (obj.type_.form == ORB.Proc) and (obj.type_.nofpar == 0) and (obj.type_.base == ORB.noType)): Files.WriteString(R, obj.name) Files.WriteInt(R, obj.val) obj = obj.next Files.Write(R, 0x0) Files.WriteInt(R, nofent) Files.WriteInt(R, entry) obj = ORB.topScope.next while obj != None: # (*entries*) if obj.exno != 0: if (obj.class_ == ORB.Const) and (obj.type_.form == ORB.Proc) or ( obj.class_ == ORB.Var): Files.WriteInt(R, obj.val) elif obj.class_ == ORB.Typ: if obj.type_.form == ORB.Record: Files.WriteInt(R, obj.type_.len_ % 0x10000) elif (obj.type_.form == ORB.Pointer) and ((obj.type_.base.typobj == None) or (obj.type_.base.typobj.exno == 0)): Files.WriteInt(R, obj.type_.base.len_ % 0x10000) obj = obj.next obj = ORB.topScope.next while obj != None: # (*pointer variables*) if obj.class_ == ORB.Var: FindPtrs(R, obj.type_, obj.val) obj = obj.next Files.WriteInt(R, -1) Files.WriteInt(R, fixorgP) Files.WriteInt(R, fixorgD) Files.WriteInt(R, fixorgT) Files.WriteInt(R, entry) Files.Write(R, "O")
def selector(x): global sym while ((sym == ORS.lbrak) or (sym == ORS.period) or (sym == ORS.arrow) or (sym == ORS.lparen) and (x.type_.form in [ORB.Record, ORB.Pointer])): if sym == ORS.lbrak: while True: sym = ORS.Get() y = ORG.Item() expression(y) if x.type_.form == ORB.Array: CheckInt(y) ORG.Index(x, y) x.type_ = x.type_.base else: ORS.Mark("not an array") if sym != ORS.comma: break Check(ORS.rbrak, "no ]") elif sym == ORS.period: sym = ORS.Get() if sym == ORS.ident: if x.type_.form == ORB.Pointer: ORG.DeRef(x) x.type_ = x.type_.base if x.type_.form == ORB.Record: obj = ORB.thisfield(x.type_) sym = ORS.Get() if obj != None: ORG.Field(x, obj) x.type_ = obj.type_ else: ORS.Mark("undef") else: ORS.Mark("not a record") else: ORS.Mark("ident?") elif sym == ORS.arrow: sym = ORS.Get() if x.type_.form == ORB.Pointer: ORG.DeRef(x) x.type_ = x.type_.base else: ORS.Mark("not a pointer") elif (sym == ORS.lparen) and (x.type_.form in [ ORB.Record, ORB.Pointer ]): # (*type_ guard*) sym = ORS.Get() if sym == ORS.ident: obj = qualident() if obj.class_ == ORB.Typ: TypeTest(x, obj.type_, True) else: ORS.Mark("guard type_ expected") else: ORS.Mark("not an identifier") Check(ORS.rparen, " ) missing")
def Module(): global sym, modid ## VAR key: LONGINT; ## obj: ORB.Object; ## impid, impid1: ORS.Ident; print " compiling ", sym = ORS.Get() if sym == ORS.module: sym = ORS.Get() if sym == ORS.times: version = 0 print "*", sym = ORS.Get() else: version = 1 ORB.Init() ORB.OpenScope() if sym == ORS.ident: modid = ORS.CopyId() sym = ORS.Get() print modid, else: ORS.Mark("identifier expected") Check(ORS.semicolon, "no ;") level = 0 dc = 0 exno = 1 key = 0 if sym == ORS.import_: sym = ORS.Get() while sym == ORS.ident: impid = ORS.CopyId() sym = ORS.Get() if sym == ORS.becomes: sym = ORS.Get() if sym == ORS.ident: impid1 = ORS.CopyId() sym = ORS.Get() else: ORS.Mark("id_ expected") else: impid1 = impid ORB.Import(impid, impid1) if sym == ORS.comma: sym = ORS.Get() elif sym == ORS.ident: ORS.Mark("comma missing") Check(ORS.semicolon, "no ;") obj = ORB.topScope.next ORG.Open(version) dc = Declarations(dc) ORG.SetDataSize((dc + 3) / 4 * 4) while sym == ORS.procedure: ProcedureDecl() Check(ORS.semicolon, "no ;") ORG.Header() if sym == ORS.begin: sym = ORS.Get() StatSequence() Check(ORS.end, "no END") if sym == ORS.ident: if ''.join(ORS.id_) != modid: ORS.Mark("no match") sym = ORS.Get() else: ORS.Mark("identifier missing") if sym != ORS.period: ORS.Mark("period missing") if ORS.errcnt == 0: ORB.Export(modid, newSF, key) if newSF: print print "new symbol file " if ORS.errcnt == 0: ORG.Close(modid, key, exno) print print "compilation done ", ORG.pc, dc, else: print print "compilation FAILED" print ORB.CloseScope() pbsList = None else: ORS.Mark("must start with MODULE")
def ProcedureDecl(): global sym, exno, level ## VAR proc: ORB.Object; ## type_: ORB.Type; ## procid: ORS.Ident; ## x: ORG.Item; ## locblksize, parblksize, L: LONGINT; ## int_: BOOLEAN; int_ = False x = ORG.Item() sym = ORS.Get() if sym == ORS.times: sym = ORS.Get() int_ = True if sym == ORS.ident: procid = ORS.CopyId() sym = ORS.Get() # (*Texts.WriteLn(W); Texts.WriteString(W, procid); Texts.WriteInt(W, ORG.Here(), 7);*) proc = ORB.NewObj(''.join(ORS.id_), ORB.Const) parblksize = 4 type_ = ORB.Type() type_.form = ORB.Proc type_.size = ORG.WordSize proc.type_ = type_ proc.expo = CheckExport() if proc.expo: proc.exno = exno exno += 1 ORB.OpenScope() level += 1 proc.val = -1 type_.base = ORB.noType parblksize = ProcedureType(type_, parblksize) # (*formal parameter list*) Check(ORS.semicolon, "no ;") locblksize = parblksize locblksize = Declarations(locblksize) proc.val = ORG.Here() * 4 proc.type_.dsc = ORB.topScope.next if sym == ORS.procedure: L = 0 L = ORG.FJump(L) while True: ProcedureDecl() Check(ORS.semicolon, "no ;") if sym != ORS.procedure: break ORG.FixLink(L) proc.val = ORG.Here() * 4 proc.type_.dsc = ORB.topScope.next ORG.Enter(parblksize, locblksize, int_) if sym == ORS.begin: sym = ORS.Get() StatSequence() if sym == ORS.return_: sym = ORS.Get() expression(x) if type_.base == ORB.noType: ORS.Mark("this is not a function") elif not CompTypes(type_.base, x.type_, False): ORS.Mark("wrong result type_") elif type_.base.form != ORB.NoTyp: ORS.Mark("function without result") type_.base = ORB.noType ORG.Return(type_.base.form, x, locblksize, int_) ORB.CloseScope() level -= 1 Check(ORS.end, "no END") if sym == ORS.ident: if ''.join(ORS.id_) != procid: ORS.Mark("no match") sym = ORS.Get() else: ORS.Mark("no proc id_") int_ = False
def Declarations(varsize): global sym, id_, exno, pbsList ## VAR obj, first: ORB.Object; ## x: ORG.Item; tp: ORB.Type; ptbase: PtrBase; ## expo: BOOLEAN; id_: ORS.Ident; # (*sync*) x = ORG.Item() obj = ORB.Object() tp = ORB.Type() pbsList = None if (sym < ORS.const) and (sym != ORS.end): ORS.Mark("declaration?") while True: sym = ORS.Get() if (sym >= ORS.const) or (sym == ORS.end): break if sym == ORS.const: sym = ORS.Get() while sym == ORS.ident: id_ = ORS.CopyId() sym = ORS.Get() expo = CheckExport() if sym == ORS.eql: sym = ORS.Get() else: ORS.Mark("= ?") expression(x) if (x.type_.form == ORB.String) and (x.b == 2): ORG.StrToChar(x) obj = ORB.NewObj(id_, ORB.Const) obj.expo = expo if x.mode == ORB.Const: obj.val = x.a obj.lev = x.b obj.type_ = x.type_ else: ORS.Mark("expression not constant") obj.type_ = ORB.intType Check(ORS.semicolon, "; missing") if sym == ORS.type_: sym = ORS.Get() while sym == ORS.ident: id_ = ORS.CopyId() sym = ORS.Get() expo = CheckExport() if sym == ORS.eql: sym = ORS.Get() else: ORS.Mark("=?") tp = Type(tp) obj = ORB.NewObj(id_, ORB.Typ) obj.type_ = tp obj.expo = expo obj.lev = level tp.typobj = obj if expo and (obj.type_.form == ORB.Record): obj.exno = exno exno += 1 else: obj.exno = 0 if tp.form == ORB.Record: ptbase = pbsList # (*check whether this is base of a pointer type_; search and fixup*) while ptbase != None: if obj.name == ptbase.name: if ptbase.type_.base == ORB.intType: ptbase.type_.base = obj.type_ else: ORS.Mark("recursive record?") ptbase = ptbase.next tp.len_ = dc if level == 0: ORG.BuildTD( tp, dc) # (*type_ descriptor; len_ used as its address*) Check(ORS.semicolon, "; missing") if sym == ORS.var: sym = ORS.Get() while sym == ORS.ident: first = IdentList(ORB.Var) tp = Type(tp) obj = first while obj != None: obj.type_ = tp obj.lev = level if tp.size > 1: varsize = (varsize + 3) / 4 * 4 # (*align*) obj.val = varsize varsize = varsize + obj.type_.size if obj.expo: obj.exno = exno exno += 1 obj = obj.next Check(ORS.semicolon, "; missing") varsize = (varsize + 3) / 4 * 4 ptbase = pbsList while ptbase != None: if ptbase.type_.base.form == ORB.Int: ORS.Mark("undefined pointer base of") ptbase = ptbase.next if (sym >= ORS.const) and (sym <= ORS.var): ORS.Mark("declaration in bad order") return varsize
def Type(type_): global sym, pbsList # VAR dmy: LONGINT; obj: ORB.Object; ptbase: PtrBase; type_ = copy(ORB.intType) # (*sync*) obj = ORB.Object() if (sym != ORS.ident) and (sym < ORS.array): ORS.Mark("not a type_") while True: sym = ORS.Get() if (sym == ORS.ident) or (sym >= ORS.array): break if sym == ORS.ident: obj = qualident() if obj.class_ == ORB.Typ: if (obj.type_ != None) and (obj.type_.form != ORB.NoTyp): type_ = obj.type_ else: ORS.Mark("not a type_ or undefined") elif sym == ORS.array: sym = ORS.Get() type_ = ArrayType(type_) elif sym == ORS.record: sym = ORS.Get() type_ = RecordType(type_) Check(ORS.end, "no END") elif sym == ORS.pointer: sym = ORS.Get() Check(ORS.to, "no TO") type_ = ORB.Type() type_.form = ORB.Pointer type_.size = ORG.WordSize type_.base = ORB.intType if sym == ORS.ident: obj = ORB.thisObj() sym = ORS.Get() if obj != None: if (obj.class_ == ORB.Typ) and (obj.type_.form in {ORB.Record, ORB.NoTyp}): type_.base = obj.type_ else: ORS.Mark("no valid base type_") ptbase = PtrBase() ptbase.name = ORS.CopyId() ptbase.type_ = type_ ptbase.next = pbsList pbsList = ptbase else: type_.base = Type(type_.base) if type_.base.form != ORB.Record: ORS.Mark("must point to record") elif sym == ORS.procedure: sym = ORS.Get() ORB.OpenScope() type_ = ORB.Type() type_.form = ORB.Proc type_.size = ORG.WordSize ProcedureType(type_, 0) type_.dsc = ORB.topScope.next ORB.CloseScope() else: ORS.Mark("illegal type_") return type_
def RecordType(type_): global sym ## VAR obj, obj0, new, bot, base: ORB.Object; ## typ, tp: ORB.Type; ## offset, off, n: LONGINT; typ = ORB.Type() typ.form = ORB.NoTyp typ.base = None typ.mno = level typ.nofpar = 0 offset = 0 bot = None if sym == ORS.lparen: sym = ORS.Get() # (*record extension*) if sym == ORS.ident: base = qualident() if base.class_ == ORB.Typ: if base.type_.form == ORB.Record: typ.base = base.type_ else: typ.base = ORB.intType ORS.Mark("invalid extension") typ.nofpar = typ.base.nofpar + 1 # (*"nofpar" here abused for extension level*) bot = typ.base.dsc offset = typ.base.size else: ORS.Mark("type_ expected") else: ORS.Mark("ident expected") Check(ORS.rparen, "no )") while sym == ORS.ident: # (*fields*) n = 0 obj = bot while sym == ORS.ident: obj0 = obj while (obj0 != None) and (obj0.name != ORS.id_): obj0 = obj0.next if obj0 != None: ORS.Mark("mult def") new = ORB.Object() new.name = ORS.CopyId() new.class_ = ORB.Fld new.next = obj obj = new n += 1 sym = ORS.Get() new.expo = CheckExport() if (sym != ORS.comma) and (sym != ORS.colon): ORS.Mark("comma expected") elif sym == ORS.comma: sym = ORS.Get() Check(ORS.colon, "colon expected") tp = ORB.Type() tp = Type(tp) if (tp.form == ORB.Array) and (tp.len_ < 0): ORS.Mark("dyn array not allowed") if tp.size > 1: offset = (offset + 3) / 4 * 4 offset = offset + n * tp.size off = offset obj0 = obj while obj0 != bot: obj0.type_ = tp obj0.lev = 0 off = off - tp.size obj0.val = off obj0 = obj0.next bot = obj if sym == ORS.semicolon: sym = ORS.Get() elif sym != ORS.end: ORS.Mark(" ; or END") typ.form = ORB.Record typ.dsc = bot typ.size = offset type_ = typ return type_
if ORS.errcnt == 0: ORB.Export(modid, newSF, key) if newSF: print print "new symbol file " if ORS.errcnt == 0: ORG.Close(modid, key, exno) print print "compilation done ", ORG.pc, dc, else: print print "compilation FAILED" print ORB.CloseScope() pbsList = None else: ORS.Mark("must start with MODULE") def Compile(T, beg=0): ORS.Init(T, beg) Module() print "OR Compiler 5.11.2013" dummy = ORB.Object() dummy.class_ = ORB.Var dummy.type_ = copy(ORB.intType)
def Type(type_): global sym, pbsList # VAR dmy: LONGINT; obj: ORB.Object; ptbase: PtrBase; type_ = copy(ORB.intType) # (*sync*) obj = ORB.Object() if (sym != ORS.ident) and (sym < ORS.array): ORS.Mark("not a type_") while True: sym = ORS.Get() if (sym == ORS.ident) or (sym >= ORS.array): break if sym == ORS.ident: obj = qualident() if obj.class_ == ORB.Typ: if (obj.type_ != None) and (obj.type_.form != ORB.NoTyp): type_ = obj.type_ else: ORS.Mark("not a type_ or undefined") elif sym == ORS.array: sym = ORS.Get() type_ = ArrayType(type_) elif sym == ORS.record: sym = ORS.Get() type_ = RecordType(type_) Check(ORS.end, "no END") elif sym == ORS.pointer: sym = ORS.Get() Check(ORS.to, "no TO"); type_ = ORB.Type() type_.form = ORB.Pointer type_.size = ORG.WordSize type_.base = ORB.intType; if sym == ORS.ident: obj = ORB.thisObj() sym = ORS.Get(); if obj != None: if (obj.class_ == ORB.Typ) and (obj.type_.form in {ORB.Record, ORB.NoTyp}): type_.base = obj.type_ else: ORS.Mark("no valid base type_") ptbase = PtrBase() ptbase.name = ORS.CopyId() ptbase.type_ = type_ ptbase.next = pbsList pbsList = ptbase else: type_.base = Type(type_.base) if type_.base.form != ORB.Record: ORS.Mark("must point to record") elif sym == ORS.procedure: sym = ORS.Get() ORB.OpenScope() type_ = ORB.Type() type_.form = ORB.Proc type_.size = ORG.WordSize ProcedureType(type_, 0) type_.dsc = ORB.topScope.next ORB.CloseScope() else: ORS.Mark("illegal type_") return type_