Exemplo n.º 1
0
def simpleExpression():
    """
    Parses
        simpleExpression = ["+" | "-"] term {("+" | "-" | "or") term}.
    Generates code for the simpleExpression if no error is reported
    """
    if SC.sym == PLUS:
        getSym(); x = term()
    elif SC.sym == MINUS:
        getSym(); x = term()
        if x.tp != Int: mark('bad type')
        elif type(x) == Const: x.val = - x.val # constant folding
        else: x = genUnaryOp(MINUS, x)
    else: x = term()
    while SC.sym in {PLUS, MINUS, OR}:
        op = SC.sym; getSym()
        if op == OR and type(x) != Const: x = genUnaryOp(OR, x)
        y = term() # x op y
        if x.tp == Int == y.tp and op in {PLUS, MINUS}:
            if type(x) == Const == type(y): # constant folding
                if op == PLUS: x.val = x.val + y.val
                elif op == MINUS: x.val = x.val - y.val
            else: x = genBinaryOp(op, x, y)
        elif x.tp == Bool == y.tp and op == OR:
            if type(x) == Const: # constant folding
                if not x.val: x = y # if x is false, take y, else x
            else: x = genBinaryOp(OR, x, y)
        else: mark('bad type')
    return x
Exemplo n.º 2
0
def simpleExpression():
    """
    Parses
        simpleExpression = ["+" | "-"] term {("+" | "-" | "or") term}.
    Generates code for the simpleExpression if no error is reported
    """
    if SC.sym == PLUS:
        getSym()
        x = term()
    elif SC.sym == MINUS:
        getSym()
        x = term()
        if x.tp != Int:
            mark("bad type")
        elif type(x) == Const:
            x.val = -x.val  # constant folding
        else:
            x = genUnaryOp(MINUS, x)
    else:
        x = term()
    while SC.sym in {PLUS, MINUS, OR}:
        op = SC.sym
        getSym()
        if op == OR and type(x) != Const:
            x = genUnaryOp(OR, x)  # -----
        y = term()  # x op y
        if x.tp == Int == y.tp and op in {PLUS, MINUS}:  # if (type(x)=int and type(y)=int) and (operator is + or -)
            if type(x) == Const == type(y):  # constant folding
                ## does x + y if they are not zero
                if op == PLUS:
                    x.val = x.val + y.val
                elif op == MINUS:
                    x.val = x.val - y.val
            else:
                print("op", op)
                print("1. simpleExpression")
                if type(x).__name__ == "Const" and x.val == 0:
                    x = y
                    print("x = y")
                    continue
                elif type(y).__name__ == "Const" and y.val == 0:
                    print("x = x")
                    x = x
                    continue
                x = genBinaryOp(op, x, y)  # does the arithmetic + and minus
        elif x.tp == Bool == y.tp and op == OR:  # no changes past here
            if type(x) == Const:  # constant folding
                if not x.val:
                    x = y  # if x is false, take y, else x
            else:
                x = genBinaryOp(OR, x, y)
        else:
            mark("bad type")
    writeln("TEST: ", "SimpleExpression: ", "5. ", "ended")

    # print("--- x: ", dir(x));
    print("function ending x: ", vars(x))
    return x
Exemplo n.º 3
0
def factor():
    """
    Parses
        factor = ident selector | integer | "(" expression ")" | "not" factor.
    Generates code for the factor if no error is reported
    """
    if SC.sym not in FIRSTFACTOR:
        mark("factor expected"); getSym()
        while SC.sym not in FIRSTFACTOR | STRONGSYMS | FOLLOWFACTOR:
            getSym()
    if SC.sym == IDENT:
        x = find(SC.val)
        if type(x) in {Var, Ref}: x = genVar(x)
        elif type(x) == Const: x = Const(x.tp, x.val); x = genConst(x)
        else: mark('variable or constant expected')
        getSym(); x = selector(x)
    elif SC.sym == NUMBER:
        x = Const(Int, SC.val); x = genConst(x); getSym()
    elif SC.sym == LPAREN:
        getSym(); x = expression()
        if SC.sym == RPAREN: getSym()
        else: mark(") expected")
    elif SC.sym == NOT:
        getSym(); x = factor()
        if x.tp != Bool: mark('not boolean')
        elif type(x) == Const: x.val = 1 - x.val # constant folding
        else: x = genUnaryOp(NOT, x)
    else:
        mark("factor expected"); x = None
    return x
Exemplo n.º 4
0
def term():
    """
    Parses
        term = factor {("*" | "div" | "mod" | "and") factor}.
    Generates code for the term if no error is reported
    """
    x = factor()
    while SC.sym in {TIMES, DIV, MOD, AND}:
        op = SC.sym
        getSym()
        if op == AND and type(x) != Const:
            x = genUnaryOp(AND, x)
        y = factor()  # x op y
        if x.tp == Int == y.tp and op in {TIMES, DIV, MOD}:
            if type(x) == Const == type(y):  # constant folding
                if op == TIMES:
                    x.val = x.val * y.val
                elif op == DIV:
                    x.val = x.val // y.val
                elif op == MOD:
                    x.val = x.val % y.val
            else:
                print("term 2: start optimization op", op)
                if type(x).__name__ == "Const" and x.val == 1:  # check if x=1 for multiplications
                    print("x == 1, do not multiply by 1")
                    x = y
                elif type(y).__name__ == "Const" and y.val == 1:  # check for imediate for multiplications
                    print("y == 1, do not multiply by 1")
                    x = x
                else:
                    x = genBinaryOp(op, x, y)
        elif x.tp == Bool == y.tp and op == AND:
            if type(x) == Const:  # constant folding
                if x.val:
                    x = y  # if x is true, take y, else x
            else:
                x = genBinaryOp(AND, x, y)
        else:
            mark("bad type")
    return x
Exemplo n.º 5
0
def term():
    """
    Parses
        term = factor {("*" | "div" | "mod" | "and") factor}.
    Generates code for the term if no error is reported
    """
    x = factor()
    while SC.sym in {TIMES, DIV, MOD, AND}:
        op = SC.sym; getSym();
        if op == AND and type(x) != Const: x = genUnaryOp(AND, x)
        y = factor() # x op y
        if x.tp == Int == y.tp and op in {TIMES, DIV, MOD}:
            if type(x) == Const == type(y): # constant folding
                if op == TIMES: x.val = x.val * y.val
                elif op == DIV: x.val = x.val // y.val
                elif op == MOD: x.val = x.val % y.val
            else: x = genBinaryOp(op, x, y)
        elif x.tp == Bool == y.tp and op == AND:
            if type(x) == Const: # constant folding
                if x.val: x = y # if x is true, take y, else x
            else: x = genBinaryOp(AND, x, y)
        else: mark('bad type')
    return x