<commit_before>module HP12c_Update_utils exposing (..)

import String
import Keyboard
import Formatting         exposing (..)

import HP12c_KeyTypes     exposing (..)
import HP12c_Model        exposing (..)



-- Update

---------- Stack operations 



liftAutomaticMemoryStack : AutomaticMemoryStackRegisters -> AutomaticMemoryStackRegisters
liftAutomaticMemoryStack currentStackRegs =
  let 
    liftedStack = { currentStackRegs | 
      reg_T = currentStackRegs.reg_Z
    , reg_Z = currentStackRegs.reg_Y
    , reg_Y = currentStackRegs.reg_X
    }
  in 
    liftedStack



liftStack : Model -> Model
liftStack model =
  let
    stackRegs = model.automaticMemoryStackRegisters
    liftedStack = liftAutomaticMemoryStack stackRegs
    liftedModel = { model | automaticMemoryStackRegisters = liftedStack }
  in
    liftedModel

exchange_X_Y_Regs : Model -> Model
exchange_X_Y_Regs model =
  let
    stackRegs = model.automaticMemoryStackRegisters
    tmp_Y = stackRegs.reg_Y
    exchangedStack = { stackRegs | 
      reg_Y = stackRegs.reg_X
    , reg_X = tmp_Y
    } 
    promotedModel = { model | automaticMemoryStackRegisters = exchangedStack, addToInputQueue   = True }
  in
    promotedModel

roll_Down_Stack : Model -> Model
roll_Down_Stack model =
  let
    stackRegs = model.automaticMemoryStackRegisters
    tmp_X = stackRegs.reg_X
    rolledStack = { stackRegs | 
      reg_X = stackRegs.reg_Y
    , reg_Y = stackRegs.reg_Z
    , reg_Z = stackRegs.reg_T
    , reg_T = tmp_X
    } 
    promotedModel = { model | automaticMemoryStackRegisters = rolledStack, addToInputQueue   = True }
  in
    promotedModel

-- g LST x lifts the stack ( unless Enter, CLx Σ+ Σ-, 12× , 12÷, was the last key pressed )
last_X : Model -> Model
last_X model =
  let
    lift_blockers =  [ Enter_Key, CL_x_Key, Sigma_Plus_Key, Sigma_Minus_Key, Times_12_Key, DIVIDE_BY_12_Key ]
    last_key_input = List.head model.inputQueue
    ( should_we_even_lift_bro, dbgmsg ) = 
      case last_key_input of 
        Just test_this_key -> 
          let 
            filtered_blockers = List.filter ( \x -> x == test_this_key ) lift_blockers
            flag =  List.isEmpty <| filtered_blockers
            msg  = " TEST:---> " ++ Basics.toString test_this_key ++  Basics.toString flag ++  " <---:" ++ Basics.toString filtered_blockers
          in 
            ( flag, msg )
        Nothing            ->  ( False, "No Head " )

    maybeLiftedModel = if should_we_even_lift_bro 
                  then liftStack model 
                  else model
    stackRegs = maybeLiftedModel.automaticMemoryStackRegisters
    maybePromotedStack = { stackRegs | 
      reg_X = stackRegs.reg_Last_X
    } 
    maybePromotedModel = 
      { maybeLiftedModel | 
        automaticMemoryStackRegisters = maybePromotedStack
      , inputMode                     = White
      , scratchRegisters  = initializeScratchRegisters
      , addToInputQueue   = True
      , message = dbgmsg
      }
    newModel = update_Display_Precision model.displayPrecision maybePromotedModel
  in
    newModel
---------- Stack operations 

---------- unaryOperators

reciprocal  x = 1/x
x_squared   x = x * x
square_root x = Basics.sqrt x
natural_log x = Basics.logBase e x
e_to_the_x  x = e ^ x
n_factorial x = 
  let 
    n = Basics.floor x
  in
    List.product [1..n] |> Basics.toFloat

-- in the hp12c platinum, the round function rounds the number to 
-- the number of decimals sepcified in the display precision
round_function : Int -> Float -> Float
round_function n x =
  let 
    float_n = Basics.toFloat n
  in 
    Basics.toFloat ( Basics.floor( x * ( 10 ^ float_n ) ) ) / ( 10 ^ float_n )
    -- TODO: check if the calc rounds it by adding 0.5

integral_part   x = Basics.toFloat ( Basics.floor x )
fractional_part x = x - ( integral_part x )


unaryOperator : ( Float -> Float ) -> Model -> Model
unaryOperator op model =
  let
    stackRegs        = model.automaticMemoryStackRegisters
    result           = ( op stackRegs.reg_X ) 
    unReducededStack = 
      { stackRegs | 
        reg_Last_X = stackRegs.reg_X
      , reg_X      = result
      } 
    scratchRegs = model.scratchRegisters
    unReducedModel = 
      { model | 
        automaticMemoryStackRegisters = unReducededStack
      , inputMode = White
      , scratchRegisters = { scratchRegs | acceptNewDigitInto = NewNumber }
      , addToInputQueue   = True
      }
    newModel = update_Display_Precision model.displayPrecision unReducedModel
  in
    newModel

---------- unaryOperators

-----------  Binary operators lhs is reg_y, rhs is reg_x

y_to_the_x     y x = y ^ x
y_plus_x       y x = y + x
y_minus_x      y x = y - x
y_times_x      y x = y * x 
y_divided_by_x y x = y / x

x_percent_of_y y x = y * x / 100
delta_percentage y x = 
  let
    sign = if y > x 
           then 1
           else -1
  in
    sign * y * ( y - x )/ 100

percentage_of_total y x = 100 * x / y 


binaryOperator_No_Down_Shift : ( Float -> Float -> Float ) -> Model -> Model 
binaryOperator_No_Down_Shift op model =
  let
    stackRegs     = model.automaticMemoryStackRegisters
    result        = ( op stackRegs.reg_Y stackRegs.reg_X )
    unPromotedStack = 
      { stackRegs | 
        reg_Last_X = stackRegs.reg_X
      , reg_X      = result
      } 
    promotedModel = 
      { model | 
        automaticMemoryStackRegisters = unPromotedStack
      , inputMode = White
      , addToInputQueue   = True
      }
    newModel = update_Display_Precision model.displayPrecision promotedModel<commit_msg>fixed delta% formula<commit_after>module HP12c_Update_utils exposing (..)

import String
import Keyboard
import Formatting         exposing (..)

import HP12c_KeyTypes     exposing (..)
import HP12c_Model        exposing (..)



-- Update

---------- Stack operations 



liftAutomaticMemoryStack : AutomaticMemoryStackRegisters -> AutomaticMemoryStackRegisters
liftAutomaticMemoryStack currentStackRegs =
  let 
    liftedStack = { currentStackRegs | 
      reg_T = currentStackRegs.reg_Z
    , reg_Z = currentStackRegs.reg_Y
    , reg_Y = currentStackRegs.reg_X
    }
  in 
    liftedStack



liftStack : Model -> Model
liftStack model =
  let
    stackRegs = model.automaticMemoryStackRegisters
    liftedStack = liftAutomaticMemoryStack stackRegs
    liftedModel = { model | automaticMemoryStackRegisters = liftedStack }
  in
    liftedModel

exchange_X_Y_Regs : Model -> Model
exchange_X_Y_Regs model =
  let
    stackRegs = model.automaticMemoryStackRegisters
    tmp_Y = stackRegs.reg_Y
    exchangedStack = { stackRegs | 
      reg_Y = stackRegs.reg_X
    , reg_X = tmp_Y
    } 
    promotedModel = { model | automaticMemoryStackRegisters = exchangedStack, addToInputQueue   = True }
  in
    promotedModel

roll_Down_Stack : Model -> Model
roll_Down_Stack model =
  let
    stackRegs = model.automaticMemoryStackRegisters
    tmp_X = stackRegs.reg_X
    rolledStack = { stackRegs | 
      reg_X = stackRegs.reg_Y
    , reg_Y = stackRegs.reg_Z
    , reg_Z = stackRegs.reg_T
    , reg_T = tmp_X
    } 
    promotedModel = { model | automaticMemoryStackRegisters = rolledStack, addToInputQueue   = True }
  in
    promotedModel

-- g LST x lifts the stack ( unless Enter, CLx Σ+ Σ-, 12× , 12÷, was the last key pressed )
last_X : Model -> Model
last_X model =
  let
    lift_blockers =  [ Enter_Key, CL_x_Key, Sigma_Plus_Key, Sigma_Minus_Key, Times_12_Key, DIVIDE_BY_12_Key ]
    last_key_input = List.head model.inputQueue
    ( should_we_even_lift_bro, dbgmsg ) = 
      case last_key_input of 
        Just test_this_key -> 
          let 
            filtered_blockers = List.filter ( \x -> x == test_this_key ) lift_blockers
            flag =  List.isEmpty <| filtered_blockers
            msg  = " TEST:---> " ++ Basics.toString test_this_key ++  Basics.toString flag ++  " <---:" ++ Basics.toString filtered_blockers
          in 
            ( flag, msg )
        Nothing            ->  ( False, "No Head " )

    maybeLiftedModel = if should_we_even_lift_bro 
                  then liftStack model 
                  else model
    stackRegs = maybeLiftedModel.automaticMemoryStackRegisters
    maybePromotedStack = { stackRegs | 
      reg_X = stackRegs.reg_Last_X
    } 
    maybePromotedModel = 
      { maybeLiftedModel | 
        automaticMemoryStackRegisters = maybePromotedStack
      , inputMode                     = White
      , scratchRegisters  = initializeScratchRegisters
      , addToInputQueue   = True
      , message = dbgmsg
      }
    newModel = update_Display_Precision model.displayPrecision maybePromotedModel
  in
    newModel
---------- Stack operations 

---------- unaryOperators

reciprocal  x = 1/x
x_squared   x = x * x
square_root x = Basics.sqrt x
natural_log x = Basics.logBase e x
e_to_the_x  x = e ^ x
n_factorial x = 
  let 
    n = Basics.floor x
  in
    List.product [1..n] |> Basics.toFloat

-- in the hp12c platinum, the round function rounds the number to 
-- the number of decimals sepcified in the display precision
round_function : Int -> Float -> Float
round_function n x =
  let 
    float_n = Basics.toFloat n
  in 
    Basics.toFloat ( Basics.floor( x * ( 10 ^ float_n ) ) ) / ( 10 ^ float_n )
    -- TODO: check if the calc rounds it by adding 0.5

integral_part   x = Basics.toFloat ( Basics.floor x )
fractional_part x = x - ( integral_part x )


unaryOperator : ( Float -> Float ) -> Model -> Model
unaryOperator op model =
  let
    stackRegs        = model.automaticMemoryStackRegisters
    result           = ( op stackRegs.reg_X ) 
    unReducededStack = 
      { stackRegs | 
        reg_Last_X = stackRegs.reg_X
      , reg_X      = result
      } 
    scratchRegs = model.scratchRegisters
    unReducedModel = 
      { model | 
        automaticMemoryStackRegisters = unReducededStack
      , inputMode = White
      , scratchRegisters = { scratchRegs | acceptNewDigitInto = NewNumber }
      , addToInputQueue   = True
      }
    newModel = update_Display_Precision model.displayPrecision unReducedModel
  in
    newModel

---------- unaryOperators

-----------  Binary operators lhs is reg_y, rhs is reg_x

y_to_the_x     y x = y ^ x
y_plus_x       y x = y + x
y_minus_x      y x = y - x
y_times_x      y x = y * x 
y_divided_by_x y x = y / x

x_percent_of_y y x = y * x / 100
delta_percentage y x = 100 * ( x - y) / y 

percentage_of_total y x = 100 * x / y 


binaryOperator_No_Down_Shift : ( Float -> Float -> Float ) -> Model -> Model 
binaryOperator_No_Down_Shift op model =
  let
    stackRegs     = model.automaticMemoryStackRegisters
    result        = ( op stackRegs.reg_Y stackRegs.reg_X )
    unPromotedStack = 
      { stackRegs | 
        reg_Last_X = stackRegs.reg_X
      , reg_X      = result
      } 
    promotedModel = 
      { model | 
        automaticMemoryStackRegisters = unPromotedStack
      , inputMode = White
      , addToInputQueue   = True
      }
    newModel = update_Display_Precision model.displayPrecision promotedModel
{'fraction_non_alphanumeric': 0.07772399305872682, 'fraction_numerical': 0.006210612841355375, 'mean_word_length': 2.412277968214397, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4515659', 'n_tokens_mistral': 3693, 'n_tokens_neox': 3488, 'n_words': 854}