def simpleExpression(sym, xItem): # sym yItem = osg.Item() if sym == Lex.plus: sym = lex.get() sym = term(sym, xItem) checkInt(xItem) elif sym == Lex.minus: sym = lex.get() sym = term(sym, xItem) checkInt(xItem) osg.Neg(xItem) else: sym = term(sym, xItem) # import pdb; pdb.set_trace() while (sym >= Lex.plus) and (sym <= Lex.or_): op = sym sym = lex.get() if op == Lex.or_: gen.Or1(xItem) checkBool(xItem) sym = term(sym, yItem) checkBool(yItem) gen.Or2(xItem, yItem) else: checkInt(xItem) sym = term(sym, yItem) checkInt(yItem) gen.AddOp(op, xItem, yItem) return sym
def selector(sym, xItem): # osg.Item yItem = osg.Item() while (sym == Lex.lbrak) or (sym == Lex.period): if sym == Lex.lbrak: sym = lex.get() sym = expression(sym, yItem) if xItem.type.form == eForm.Array: checkInt(yItem) gen.Index(xItem, yItem) xItem.type = xItem.type.base else: mark('not an array') sym = check(sym, Lex.rbrak, 'no ]') else: # period sym = lex.get() if sym == Lex.ident: if xItem.type.form == eForm.Record: obj = findField(lex.value, xItem.type.fields) sym = lex.get() gen.Field(xItem, obj) xItem.type = obj.type else: mark('not a record') else: mark('ident?') return sym
def expression(sym, xItem): # -> sym yItem = osg.Item() sym = simpleExpression(sym, xItem) if (sym >= Lex.eql) and (sym <= Lex.geq): op = sym sym = lex.get() sym = simpleExpression(sym, yItem) if xItem.type == yItem.type: gen.Relation(op, xItem, yItem) else: mark('incompatible types') xItem.type = boolType return sym
def parameter(sym, par): # osg.Object xItem = osg.Item() sym = expression(sym, xItem) varpar = par.class_ == eClass.Par if compTypes(par.type, xItem.type): if not varpar: gen.ValueParam(xItem) else: gen.VarParam(xItem, par.type) elif ( xItem.type.form == eForm.Array) and (par.type.form == eForm.Array) and \ ( xItem.type.base.form == par.type.base.form) and (par.type.len < 0) : gen.OpenArrayParam(xItem) else: mark('incompatible parameters') return sym
def sysProc(sym, pno): if sym == Lex.lparen: xItem = osg.Item() sym = lex.get() sym = expression(sym, xItem) if pno == 0: gem.ReadInt(xItem) elif pno == 1: gen.WriteInt(xItem) elif pno == 2: gen.WriteChar(xItem) elif pno == 3: gen.WriteLn() else: mark('no lparen') if sym == Lex.rparen: sym = lex.get() else: mark('no rparen') return sym
def typeDef(sym): # -> sym, type if (sym != Lex.ident) and (sym < Lex.array): mark('type?') while True: sym = lex.get() if (sym == Lex.ident) or (sym >= Lex.array): break if sym == Lex.ident: obj = find(lex.value) sym = lex.get() if obj.class_ == eClass.Type: typed = obj.type else: mark('type?') elif sym == Lex.array: xItem = osg.Item() sym = lex.get() sym = expression(sym, xItem) if (xItem.mode != eClass.Const) or (xItem.a < 0): mark('bad index') if sym == Lex.of: sym = lex.get() else: mark('OF?') sym, tp = typeDef(sym) typed = osg.TypeDesc(form=eForm.Array) typed.base = tp typed.len = xItem.a typed.size = typed.len * tp.size elif sym == Lex.record: sym = lex.get() sym = check(sym, Lex.begin, 'expecting {') typed = osg.TypeDesc(form=eForm.Record, size=0) openScope('record') while True: if sym == Lex.ident: iList = [] sym = identList(sym, iList, eClass.Field) sym, typef = typeDef(sym) for obj in iList: obj.type = typef obj.value = typed.size # offset of the field typed.size += obj.type.size # grow record size if sym == Lex.semicolon: sym = lex.get() elif sym == Lex.ident: mark('; ?') if sym != Lex.ident: break typed.fields = universe[ 0].idents # move list of fields to type descriptor closeScope() sym = check(sym, Lex.end, 'no END') else: mark('ident?') return sym, typed
def declarations(sym, varsize): # -> sym, varsize # sync xItem = osg.Item() if (sym < Lex.const) and (sym != Lex.end): mark('declaration?') while True: sym = lex.get() if (sym >= Lex.const) or (sym == Lex.end): break if sym == Lex.const: sym = lex.get() while sym == Lex.ident: obj = newObj(lex.value, eClass.Const) sym = lex.get() if sym == Lex.eql: sym = lex.get() else: mark('=?') sym = expression(sym, xItem) if xItem.mode == eClass.Const: obj.value = xItem.a obj.type = xItem.type else: mark('expression not constant') sym = check(sym, Lex.semicolon, '; expected') if sym == Lex.type: sym = lex.get() while sym == Lex.ident: obj = newObj(lex.value, eClass.Type) sym = lex.get() if sym == Lex.eql: sym = lex.get() else: mark('=?') sym, obj.type = typeDef(sym) sym = check(sym, Lex.semicolon, '; expected') if sym == Lex.var: sym = lex.get() iList = [] sym = identList(sym, iList, eClass.Var) sym, tp = typeDef(sym) for obj in iList: obj.type = tp obj.level = level obj.value = varsize # address varsize += obj.type.size sym = check(sym, Lex.semicolon, '; expected') if (sym >= Lex.const) and (sym <= Lex.var): mark('declaration in bad order') return sym, varsize
def term(sym, xItem): # -> sym yItem = osg.Item() sym = factor(sym, xItem) while (sym >= Lex.times) and (sym <= Lex.and_): op = sym sym = lex.get() if op == Lex.times: checkInt(xItem) sym = factor(sym, yItem) checkInt(yItem) osg.MulOp(xItem, yItem) elif (op == Lex.div) or (op == Lex.mod): checkInt(xItem) sym = factor(sym, yItem) checkInt(yItem) osg.DivOp(op, xItem, yItem) else: # op == and_ checkBool(xItem) osg.And1(xItem) sym = factor(sym, yItem) checkBool(yItem) osg.And2(xItem, yItem) return sym
def statSequence(sym): global level xItem = osg.Item() yItem = osg.Item() while True: if not ((sym == Lex.ident) or (sym >= Lex.if_) and (sym <= Lex.repeat) or (sym >= Lex.semicolon)): mark('statement expected') while True: sym = lex.get() if (sym == Lex.ident) or (sym >= Lex.if_): break if sym == Lex.ident: obj = find(lex.value) sym = lex.get() if obj.class_ == eClass.SProc: sym = sysProc(sym, obj.value) else: gen.MakeItem(xItem, obj, level) sym = selector(sym, xItem) if sym == Lex.becomes: # assignment sym = lex.get() sym = expression(sym, yItem) if (xItem.type.form in [ eForm.Boolean, eForm.Integer ]) and (xItem.type.form == yItem.type.form): gen.Store(xItem, yItem) else: mark('incompatible assignment') elif sym == Lex.eql: mark('should be ==') sym = lex.get() sym = expression(sym, yItem) elif sym == Lex.lparen: # procedure call sym = lex.get() if (obj.class_ == eClass.Proc) and (obj.type == None): sym = paramList(sym, obj) gen.Call(obj) else: mark('not a procedure') elif obj.class_ == eClass.Proc: # procedure call without parameters if obj.nofpar > 0: mark('missing parameters') if not obj.type: gen.Call(obj) else: mark('not a procedure') elif (obj.class_ == eClass.SProc) and (obj.value == 3): gen.WriteLn() elif obj.class_ == eClass.Type: mark('illegal assignment') else: mark('not a procedure') elif sym == Lex.if_: sym = lex.get() sym = expression(sym, xItem) checkBool(xItem) gen.CFJump(xItem) sym = check(sym, Lex.then, 'no :') sym = statSequence(sym) L = 0 while sym == Lex.elsif: sym = lex.get() L = gen.FJump(L) gen.fixLink(xItem.a) sym = expression(sym, xItem) checkBool(xItem) gen.CFJump(xItem) if sym == Lex.then: sym = lex.get() else: mark(':?') statSequence if sym == Lex.else_: sym = lex.get() L = gen.FJump(L) gen.fixLink(xItem.a) sym = statSequence(sym) else: gen.fixLink(xItem.a) gen.fixLink(L) if sym == Lex.end: sym = lex.get() else: mark('END ?') elif sym == Lex.while_: sym = lex.get() L = gen.pc sym = expression(sym, xItem) checkBool(xItem) gen.CFJump(xItem) check(Lex.do, 'no :') sym = statSequence(sym) gen.BJump(L) gen.fixLink(xItem.a) check(Lex.end, 'no END') elif sym == Lex.repeat: sym = lex.get() L = gen.pc sym = statSequence(sym) if sym == Lex.until: sym = lex.get() sym = expression(sym, xItem) checkBool(xItem) gen.CBJump(xItem, L) else: mark('missing UNTIL') sym = lex.get() gen.checkRegs() if sym == Lex.semicolon: sym = lex.get() elif sym < Lex.semicolon: mark('missing semicolon?') if sym > Lex.semicolon: break return sym