TYPE ConstFlattened = flat(snum) State = Var -> ConstFlattened PROBLEM Detection_of_Signs direction : forward carrier : State init : bot init_start : [-> top] combine : lub TRANSFER // in assignments calculate the new value of the variable and add it to the state ASSIGN(variable, expression) = @\[variable -> evalAExp(expression, @)] // in procedur calls pass the value of the actual argument to the formal parameter CALL(_, param, exp), call_edge = @\[param -> evalAExp(exp, @)] // at the end of procedures reset the formal parameter END(_, param) = @\[param -> bot] SUPPORT evalAExp :: Expression * State -> ConstFlattened evalAExp(expression, state) = case expType(expression) of "ARITH_BINARY" => case expOp(expression) of "+" => let valLeft <= evalAExp(expSubLeft(expression), state), valRight <= evalAExp(expSubRight(expression),state) in case valLeft of 1 => case valRight of 1 => lift(1); 0 => lift(1); 2 => top; endcase; 0 => case valRight of 1 => lift(1); 0 => lift(0); 2 => lift(2); endcase; 2 => case valRight of 1 => top; 0 => lift(2); 2 => lift(2); endcase; endcase; "-" => let valLeft <= evalAExp(expSubLeft(expression), state), valRight <= evalAExp(expSubRight(expression), state) in case valLeft of 1 => case valRight of 1 => top; 0 => lift(1); 2 => lift(1); endcase; 0 => case valRight of 1 => lift(2); 0 => lift(0); 2 => lift(1); endcase; 2 => case valRight of 1 => lift(2); 0 => lift(2); 2 => top; endcase; endcase; "*" => let valLeft <= evalAExp(expSubLeft(expression), state), valRight <= evalAExp(expSubRight(expression),state) in case valLeft of 1 => case valRight of 1 => lift(1); 0 => lift(0); 2 => lift(2); endcase; 0 => case valRight of 1 => lift(0); 0 => lift(0); 2 => lift(0); endcase; 2 => case valRight of 1 => lift(2); 0 => lift(0); 2 => lift(1); endcase; endcase; "/" => let valLeft <= evalAExp(expSubLeft(expression), state), valRight <= evalAExp(expSubRight(expression), state) in case valLeft of 1 => case valRight of 1 => lift(1); 0 => top; 2 => lift(2); endcase; 0 => case valRight of 1 => lift(0); 0 => top; 2 => lift(0); endcase; 2 => case valRight of 1 => lift(2); 0 => top; 2 => lift(1); endcase; endcase; endcase; "ARITH_UNARY" => case expOp(expression) of "-" => let a <= evalAExp(expSub(expression), state) in if a=1 then lift(2) else if a = 2 then lift(1) else lift(0) endif endif; endcase; "VAR" => state ( expVar(expression) ); "CONST" => let a = expVal(expression) in if a > 0 then lift(1) else if a < 0 then lift(2) else lift(0) endif endif; _ => error("Runtime Error: evalAExp applied to nonarithmetic Expression"); endcase