update instructions list/formatting

This commit is contained in:
Rowan Torbitzky-Lane 2025-02-11 17:05:16 -06:00
parent 899aaa93a7
commit 84e5c7b1df
7 changed files with 685 additions and 529 deletions

View File

@ -15,7 +15,7 @@ test: # Runs unit tests.
runghc -i./src/ test/Main.hs
format: # Formats code using ormolu.
ormolu --mode inplace app/*.hs src/*.hs test/*.hs
ormolu --mode inplace app/*.hs src/HushGP/*.hs test/*.hs
hlint: # HLint for lint suggestions.
hlint src/*.hs

View File

@ -13,7 +13,7 @@
- [X] Write haddock documentation for each function
- [X] Refactor all functions to take state as the final parameter
- [X] Standardize the pattern matching parameter names, such as c1 : cs
- [ ] Write unit/quickcheck tests for all of the instructions
- [ ] Write unit/quickcheck tests for the generic functions
~~[ ] Use template haskell to generate function lists~~
- [X] Move utility functions to their own file
- [ ] Make add/sub/mult/div/mod instructions generic

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@ module HushGP.Instructions.StringInstructions where
import HushGP.State
import HushGP.Instructions.GenericInstructions
import HushGP.Instructions.Utility
import Control.Lens
-- |Concats the top two strings on the string stack and pushes the result.
instructionStringConcat :: State -> State
@ -221,14 +220,6 @@ instructionStringStripWhitespace :: State -> State
instructionStringStripWhitespace state@(State {_string = s1 : ss}) = state{_string = strip s1 : ss}
instructionStringStripWhitespace state = state
-- |Utility Function: Casts a type based on a lens to a string. Pushes the result
-- to the string stack.
instructionStringFromLens :: Show a => Lens' State [a] -> State -> State
instructionStringFromLens accessor state@(State {_string = ss}) =
case uncons (view accessor state) of
Nothing -> state
Just (x1,_) -> state{_string = show x1 : ss}
-- |Converts the top bool from the bool stack to a string. Pushes the result to
-- the string stack.
instructionStringFromBool :: State -> State

View File

@ -247,3 +247,13 @@ lstrip s = case s of
-- this is a tad inefficient
rstrip :: String -> String
rstrip = reverse . lstrip . reverse
-- string utility
-- |Utility Function: Casts a type based on a lens to a string. Pushes the result
-- to the string stack.
instructionStringFromLens :: Show a => Lens' State [a] -> State -> State
instructionStringFromLens accessor state@(State {_string = ss}) =
case uncons (view accessor state) of
Nothing -> state
Just (x1,_) -> state{_string = show x1 : ss}

View File

@ -12,8 +12,8 @@ import HushGP.State
-- Everntually, this can be part of the apply func to state helpers,
-- which should take the number and type of parameter they have.
-- |This is one of the push genome functions itself, not infrastructure.
-- Optionally, split this off into independent functions
-- | This is one of the push genome functions itself, not infrastructure.
-- Optionally, split this off into independent functions
instructionParameterLoad :: State -> State
instructionParameterLoad state@(State {_parameter = (p : _)}) = case p of
(GeneInt val) -> state & int .~ val : view int state
@ -32,20 +32,20 @@ instructionParameterLoad state@(State {_parameter = (p : _)}) = case p of
(Block xs) -> state & exec .~ xs <> view exec state
instructionParameterLoad state = state
-- |Loads a genome into the exec stack
-- | Loads a genome into the exec stack
loadProgram :: [Gene] -> State -> State
loadProgram newstack state = state & exec .~ newstack
-- |Takes a Push state, and generates the next push state via:
-- If the first item on the EXEC stack is a single instruction
-- then pop it and execute it.
-- Else if the first item on the EXEC stack is a literal
-- then pop it and push it onto the appropriate stack.
-- Else (the first item must be a list) pop it and push all of the
-- items that it contains back onto the EXEC stack individually,
-- in reverse order (so that the item that was first in the list
-- ends up on top).
-- The empty-stack safety of interpretExec on empty stacks depends on the functions it calls.
-- | Takes a Push state, and generates the next push state via:
-- If the first item on the EXEC stack is a single instruction
-- then pop it and execute it.
-- Else if the first item on the EXEC stack is a literal
-- then pop it and push it onto the appropriate stack.
-- Else (the first item must be a list) pop it and push all of the
-- items that it contains back onto the EXEC stack individually,
-- in reverse order (so that the item that was first in the list
-- ends up on top).
-- The empty-stack safety of interpretExec on empty stacks depends on the functions it calls.
interpretExec :: State -> State
interpretExec state@(State {_exec = e : es}) =
case e of

View File

@ -8,10 +8,10 @@ import Data.Map qualified as Map
import GHC.Generics
import Test.QuickCheck
-- |The exec stack must store heterogenous types,
-- and we must be able to detect that type at runtime.
-- One solution is for the exec stack to be a list of [Gene].
-- The parameter stack could be singular [Gene] or multiple [atomic] types.
-- | The exec stack must store heterogenous types,
-- and we must be able to detect that type at runtime.
-- One solution is for the exec stack to be a list of [Gene].
-- The parameter stack could be singular [Gene] or multiple [atomic] types.
data Gene
= GeneInt Int
| GeneFloat Float
@ -83,7 +83,7 @@ instance Arbitrary Gene where
return Close
]
-- |The structure that holds all of the values.
-- | The structure that holds all of the values.
data State = State
{ _exec :: [Gene],
_code :: [Gene],