From 84442e4e3a53b5c6140ce44a8ddad12541894509 Mon Sep 17 00:00:00 2001 From: Adrian Cochrane Date: Tue, 11 Apr 2023 09:23:31 +1200 Subject: [PATCH] Reference-document (unused) calc() implementation. --- Graphics/Layout/Arithmetic.hs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Graphics/Layout/Arithmetic.hs b/Graphics/Layout/Arithmetic.hs index 50c5f45..3ee01da 100644 --- a/Graphics/Layout/Arithmetic.hs +++ b/Graphics/Layout/Arithmetic.hs @@ -7,8 +7,11 @@ import Data.Scientific (toRealFloat) import GHC.Real (infinity) import Data.Text (unpack, Text) import qualified Data.Text as Txt +import Debug.Trace (trace) -- For error reporting. +-- | Parsed calc() expression. As a postfix arithmatic expression. data Opcode n = Seq | Add | Subtract | Multiply | Divide | Func Text | Num n deriving Show +-- | Parse a calc() expression. parseCalc :: [Token] -> [Opcode (Float, String)] -> [Opcode (Float, String)] parseCalc (Number _ n:toks) stack = Num (val2float n, ""):parseCalc toks stack parseCalc (Percentage _ n:toks) stack = Num (val2float n, "%"):parseCalc toks stack @@ -45,6 +48,7 @@ parseCalc [] [] = [] parseCalc [] stack = parseCalc [RightParen] stack parseCalc _ _ = [Func "invalid"] +-- | Parse an operator char. op :: Char -> Opcode n op '+' = Add op '-' = Subtract @@ -55,6 +59,7 @@ op _ = Func "invalid" -- Do operands counts line up? Are we dividing by 0? -- Also I see concerns about whether units line up. Not bothering verifying that. +-- | Verify that a parsed math expression can be properly evaluated. verifyCalc :: [Opcode (Float, String)] -> [Bool] -> Bool verifyCalc (Seq:expr) stack = verifyCalc expr stack verifyCalc (Add:expr) (_:_:stack) = verifyCalc expr (True:stack) @@ -72,6 +77,7 @@ verifyCalc (Func "clamp":expr) (_:_:_:stack) = verifyCalc expr (True:stack) verifyCalc [] [_] = True verifyCalc _ _ = False +-- | Evaluate a parsed calc() expression. evalCalc :: [Opcode Float] -> [Float] -> Float evalCalc (Seq:expr) stack = evalCalc expr stack -- The function args off evalCalc (Add:expr) (y:x:stack) = evalCalc expr ((x + y):stack) @@ -103,8 +109,15 @@ evalCalc (Func "sqrt":expr) (x:stack) = evalCalc expr (sqrt x:stack) evalCalc (Func "tan":expr) (x:stack) = evalCalc expr (tan x:stack) evalCalc [] [ret] = ret -evalCalc _ _ = error "Verification should have caught this error!" +evalCalc [] stack@(ret:_) = + trace ("Verification should have caught this error! " ++ show stack) ret +evalCalc [] [] = trace "Verification should have caught this error! Stack underflow!" 0 +evalCalc (op:_) (ret:_) = + trace ("Verification should have caught this error! Unsupported op " ++ show op) ret +evalCalc (op:_) [] = + trace ("Verification should have caught this error! Unsupported op " ++ show op) 0 +-- | Convert all numbers in an expression via the given callback. mapCalc :: (a -> b) -> [Opcode a] -> [Opcode b] mapCalc cb (Num x:toks) = Num (cb x):mapCalc cb toks -- GHC demanded more verbosity... @@ -116,9 +129,11 @@ mapCalc cb (Divide:toks) = Divide:mapCalc cb toks mapCalc cb (Func f':toks) = Func f':mapCalc cb toks mapCalc _ [] = [] +-- | Convert from a tokenized NumericValue to a Float. val2float :: NumericValue -> Float val2float (NVInteger n) = fromIntegral n val2float (NVNumber n) = toRealFloat n +-- | Convert from a rational value to a float. f :: Rational -> Float f = fromRational -- 2.30.2