Esempio n. 1
0
def SimpleExpression():
    if lex() in {Lex.PLUS, Lex.MINUS}:
        op = lex()
        nextLex()
        p = loc.lexPos
        T = Term()
        testInt(T, p)
        if op == Lex.MINUS:
            Gen(cm.NEG)
    else:
        p = loc.lexPos
        T = Term()

    while lex() in {Lex.PLUS, Lex.MINUS}:
        op = lex()
        testInt(T, p)
        nextLex()
        p = loc.lexPos
        T = Term()
        testInt(T, p)
        if op == Lex.PLUS:
            Gen(cm.ADD)
        else:
            Gen(cm.SUB)

    return T
Esempio n. 2
0
def Function(x: cat.Func):
    if x.name == "ABS":
        intExpr()
        Gen(cm.DUP)
        gen.Const(0)
        Gen(gen.PC + 3)
        Gen(cm.IFGE)
        Gen(cm.NEG)
    elif x.name == "MIN":
        check(Lex.NAME)
        x = table.find(scan.name())
        if type(x) != cat.Type:
            Expected("имя типа")
        nextLex()
        Gen(scan.MAXINT)
        Gen(cm.NEG)
        Gen(1)
        Gen(cm.SUB)
    elif x.name == "MAX":
        check(Lex.NAME)
        x = table.find(scan.name())
        if type(x) != cat.Type:
            Expected("имя типа")
        nextLex()
        gen.Const(scan.MAXINT)
    elif x.name == "ODD":
        intExpr()
        Gen(1)
        Gen(cm.MOD)
        Gen(0)
        Gen(cm.IFNE)
    else:
        assert False
Esempio n. 3
0
def Compile():
    T = Types

    table.openScope()

    table.add(cat.Func("ABS", T.Int))
    table.add(cat.Func("MAX", T.Int))
    table.add(cat.Func("MIN", T.Int))
    table.add(cat.Func("ODD", T.Bool))
    table.add(cat.Proc("HALT"))
    table.add(cat.Proc("INC"))
    table.add(cat.Proc("DEC"))
    table.add(cat.Proc("In.Open"))
    table.add(cat.Proc("In.Int"))
    table.add(cat.Proc("Out.Int"))
    table.add(cat.Proc("Out.Ln"))
    table.add(cat.Type("INTEGER", T.Int))

    text.nextCh()
    nextLex()

    table.openScope()

    Module()

    table.closeScope()
    table.closeScope()
Esempio n. 4
0
def Import():
    skip(Lex.IMPORT)
    ImportName()
    while lex() == Lex.COMMA:
        nextLex()
        ImportName()
    skip(Lex.SEMI)
Esempio n. 5
0
def Factor():
    T = None
    if lex() == Lex.NUM:
        Gen(scan.num())
        nextLex()
        T = Types.Int
    elif lex() == Lex.NAME:
        x = table.find(scan.name())
        if type(x) == cat.Var:
            gen.Addr(x)
            Gen(cm.LOAD)
            nextLex()
            T = x.type
        elif type(x) == cat.Const:
            gen.Const(x.val)
            T = x.type
            nextLex()
        elif type(x) == cat.Func:
            nextLex()
            skip(Lex.LPAR)
            Function(x)
            T = x.type
            skip(Lex.RPAR)
        else:
            Expected("функция, константа или переменная")
    elif lex() == Lex.LPAR:
        nextLex()
        T = Expression()
        skip(Lex.RPAR)
    else:
        Expected("имя число или выражение в скобках")
    return T
Esempio n. 6
0
def IfStatement():
    skip(Lex.IF)
    p = loc.lexPos
    boolExpr()
    lastGOTO = 0
    condPC = gen.PC
    skip(Lex.THEN)
    StatSeq()
    while lex() == Lex.ELSIF:
        Gen(lastGOTO)
        Gen(cm.GOTO)
        lastGOTO = gen.PC
        fixup(condPC, gen.PC)
        nextLex()
        p = loc.lexPos
        boolExpr()
        skip(Lex.THEN)
        StatSeq()
    if lex() == Lex.ELSE:
        nextLex()
        Gen(lastGOTO)
        Gen(cm.GOTO)
        lastGOTO = gen.PC
        fixup(condPC, gen.PC)
        StatSeq()
    else:
        fixup(condPC, gen.PC)

    skip(Lex.END)
    fixup(lastGOTO, gen.PC)
Esempio n. 7
0
def Variable():
    check(Lex.NAME)
    x = table.find(scan.name())
    if type(x) == cat.Var:
        gen.Addr(x)
    else:
        Expected("переменная")
    nextLex()
Esempio n. 8
0
def DeclSeq():
    while lex() in {Lex.CONST, Lex.VAR}:
        if lex() == Lex.CONST:
            nextLex()
            ConstDecl()
        else:
            nextLex()
            varDecl()
Esempio n. 9
0
def ConstDecl():
    while lex() == Lex.NAME:
        ident = scan.name()
        nextLex()
        skip(Lex.EQ)
        val = ConstExpr()
        table.new(cat.Const(ident, val, Types.Int))
        skip(Lex.SEMI)
Esempio n. 10
0
def Expression():
    p = loc.lexPos
    T = SimpleExpression()
    if lex() in {Lex.EQ, Lex.NE, Lex.GE, Lex.GT, Lex.LE, Lex.LT}:
        op = lex()
        testInt(T, p)
        nextLex()
        p = loc.lexPos
        T = SimpleExpression()
        testInt(T, p)
        T = Types.Bool
        gen.Comp(op)
    return T
Esempio n. 11
0
def Term():
    p = loc.lexPos
    T = Factor()
    while lex() in {Lex.MULT, Lex.MOD, Lex.DIV}:
        op = lex()
        testInt(T, p)
        nextLex()
        p = loc.lexPos
        Factor()
        testInt(T, p)
        if op == Lex.MULT:
            Gen(cm.MULT)
        elif op == Lex.DIV:
            Gen(cm.DIV)
        else:
            Gen(cm.MOD)

    return T
Esempio n. 12
0
def Module():
    skip(Lex.MODULE)
    if lex() == Lex.NAME:
        modRef = table.new(cat.Module(scan.name()))
        nextLex()
    else:
        Expected("имя")
    skip(Lex.SEMI)
    L = lex()
    if lex() == Lex.IMPORT:
        Import()
    DeclSeq()
    if lex() == Lex.BEGIN:
        nextLex()
        StatSeq()
    skip(Lex.END)
    check(Lex.NAME)
    x = table.find(scan.name())
    if x != modRef:
        Expected(f"имя модуля {modRef.name}")
    nextLex()
    skip(Lex.DOT)
    Gen(cm.STOP)

    AllocVars()
Esempio n. 13
0
def Procedure(x):
    if x.name == "HALT":
        gen.Const(ConstExpr())
        Gen(cm.STOP)
    elif x.name == "INC":
        Variable()
        Gen(cm.DUP)
        Gen(cm.LOAD)
        if lex() == Lex.COMMA:
            nextLex()
            intExpr()
        else:
            gen.Const(1)
        Gen(cm.ADD)
        Gen(cm.SAVE)
    elif x.name == "DEC":
        Variable()
        Gen(cm.DUP)
        Gen(cm.LOAD)
        if lex() == Lex.COMMA:
            nextLex()
            intExpr()
        else:
            gen.Const(1)
        Gen(cm.SUB)
        Gen(cm.SAVE)
    elif x.name == "In.Int":
        Variable()
        Gen(cm.IN)
        Gen(cm.SAVE)
    elif x.name == "Out.Int":
        intExpr()
        skip(Lex.COMMA)
        intExpr()
        Gen(cm.OUT)
    elif x.name == "Out.Ln":
        Gen(cm.LN)
    elif x.name == "In.Open":
        pass
Esempio n. 14
0
def varDecl():
    while lex() == Lex.NAME:
        table.new(cat.Var(scan.name(), Types.Int, 0))
        nextLex()
        while lex() == Lex.COMMA:
            nextLex()
            check(Lex.NAME)
            table.new(cat.Var(scan.name(), Types.Int, 0))
            nextLex()
        skip(Lex.COLON)
        Type()
        skip(Lex.SEMI)
Esempio n. 15
0
def ConstExpr():
    sign = -1 if lex() == Lex.MINUS else +1
    if lex() in {Lex.PLUS, Lex.MINUS}:
        nextLex()
    if lex() == Lex.NUM:
        val = sign * scan.num()
        nextLex()
    elif lex() == Lex.NAME:
        const = table.find(scan.name())
        if type(const) != cat.Const:
            Expected("константа")
        val = sign * const.val
        nextLex()
    else:
        Expected("константа")
    return val
Esempio n. 16
0
def AssOrCall():
    check(Lex.NAME)
    x = table.find(scan.name())
    nextLex()
    if type(x) == cat.Module:
        module = x.name
        skip(Lex.DOT)
        check(Lex.NAME)
        pname = module + "." + scan.name()
        x = table.find(pname)
        if type(x) == cat.Proc:
            nextLex()
            if lex() == Lex.LPAR:
                nextLex()
                Procedure(x)
                skip(Lex.RPAR)
            else:
                Procedure(x)
        else:
            Expected("процедура")
    elif type(x) == cat.Proc:
        if lex() == Lex.LPAR:
            nextLex()
            Procedure(x)
            skip(Lex.RPAR)
        else:
            Procedure(x)
    elif type(x) == cat.Var:
        gen.Addr(x)
        skip(Lex.ASS)
        p = loc.lexPos
        T = Expression()
        if T != x.type:
            posError("Несоответствие типа", p)
        Gen(cm.SAVE)
    else:
        Expected("вызов процедуры или присваивание")
Esempio n. 17
0
def Type():
    check(Lex.NAME)
    x = table.find(scan.name())
    if type(x) != cat.Type:
        Expected("имя типа")
    nextLex()
Esempio n. 18
0
def skip(L):
    if lex() == L:
        nextLex()
    else:
        Expected(lexName(L))
Esempio n. 19
0
def ImportName():
    check(Lex.NAME)
    if scan.name() not in {"In", "Out"}:
        cntError("Неизвестный модуль")
    table.new(cat.Module(scan.name()))
    nextLex()
Esempio n. 20
0
def StatSeq():
    Statement()
    while lex() == Lex.SEMI:
        nextLex()
        Statement()