示例#1
0
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
示例#2
0
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
示例#3
0
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
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
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
示例#8
0
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
示例#9
0
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