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
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
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
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
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