Skip to content

Instantly share code, notes, and snippets.

@folkertdev
Created February 9, 2017 21:23
Show Gist options
  • Save folkertdev/93bd8964087801be17a9a42eb125701b to your computer and use it in GitHub Desktop.
Save folkertdev/93bd8964087801be17a9a42eb125701b to your computer and use it in GitHub Desktop.
Experiment to create an elm fuzzer for an Abstract Syntax Tree
module ExpressionFuzzer exposing (..)
import Char
import Fuzz exposing (Fuzzer, frequencyOrCrash, intRange, constant)
import Lazy as L
-- origionally by slack user stil4m
type ExprPart
= Literal String
| Operator ExprPart String ExprPart
| Parenthesized ExprPart
expression : Fuzzer String
expression =
exprPart |> Fuzz.map exprToString
exprToString : ExprPart -> String
exprToString x =
case x of
Literal x ->
x
Operator left x right ->
String.concat [ exprToString left, x, exprToString right ]
Parenthesized x ->
wrapInParens (exprToString x)
wrapInParens : String -> String
wrapInParens s =
"(" ++ s ++ ")"
exprPart : Fuzzer ExprPart
exprPart =
L.force <|
L.lazy <|
\() ->
frequencyOrCrash
[ ( 2.0, literal )
, ( 1.0, operator )
, ( 0.5, parenthesized )
]
operator : Fuzzer ExprPart
operator =
L.force <|
L.lazy <|
\() ->
Fuzz.map3 Operator exprPart operatorToken exprPart
operatorToken : Fuzzer String
operatorToken =
[ "+", "-", "/", "*" ]
|> List.map (constant >> (,) 1.0)
|> frequencyOrCrash
parenthesized : Fuzzer ExprPart
parenthesized =
L.force <|
L.lazy <|
\() ->
Fuzz.map Parenthesized exprPart
literal : Fuzzer ExprPart
literal =
Fuzz.map Literal <|
frequencyOrCrash
[ ( 0.5, number )
, ( 0.5, variable )
]
number : Fuzzer String
number =
intRange 1 100 |> Fuzz.map toString
variable : Fuzzer String
variable =
intRange 97 (97 + 26)
|> Fuzz.map (Char.fromCode >> String.fromChar)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment