summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2022-01-01 16:33:21 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2022-01-01 16:33:21 +0100
commitb2d29a6ec8d55cebaae7cbff86375f05c77c2d11 (patch)
treeab628047ebe293b90ee1fda36b48dd23d57dc1d0
parentf86032ff459f57c8cda368b48888a39c848d263b (diff)
Woops, forgot that file.
-rw-r--r--src/Tonkadur/Json.elm403
1 files changed, 403 insertions, 0 deletions
diff --git a/src/Tonkadur/Json.elm b/src/Tonkadur/Json.elm
new file mode 100644
index 0000000..3860548
--- /dev/null
+++ b/src/Tonkadur/Json.elm
@@ -0,0 +1,403 @@
+module Tonkadur.Json exposing (decoder)
+
+-- Elm -------------------------------------------------------------------------
+import Array
+import Dict
+import List
+import Random
+
+import Json.Decode
+import Json.Decode.Pipeline
+
+-- Tonkadur --------------------------------------------------------------------
+import Tonkadur.Types
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+---- COMPUTATIONS --------------------------------------------------------------
+specific_computation_decoder : (
+ String ->
+ (Json.Decode.Decoder Tonkadur.Types.Computation)
+ )
+specific_computation_decoder name =
+ case name of
+ "add_text_effect" ->
+ (Json.Decode.map3
+ (\ename params content ->
+ (Tonkadur.Types.AddTextEffect ename params content)
+ )
+ (Json.Decode.field "effect" (Json.Decode.string))
+ (Json.Decode.field
+ "parameters"
+ (Json.Decode.list (computation_decoder))
+ )
+ (Json.Decode.field
+ "content"
+ (Json.Decode.list (computation_decoder))
+ )
+ )
+
+ "address" ->
+ (Json.Decode.map
+ (\address -> (Tonkadur.Types.Address address))
+ (Json.Decode.field "address" (computation_decoder))
+ )
+
+ "cast" ->
+ (Json.Decode.map3
+ (\from to value -> (Tonkadur.Types.Cast from to value))
+ (Json.Decode.field "from" (Json.Decode.string))
+ (Json.Decode.field "to" (Json.Decode.string))
+ (Json.Decode.field "content" (computation_decoder))
+ )
+
+ "constant" ->
+ (Json.Decode.map2
+ (\type_name value -> (Tonkadur.Types.Constant type_name value))
+ (Json.Decode.field "type" (Json.Decode.string))
+ (Json.Decode.field "value" (Json.Decode.string))
+ )
+
+ "get_allocable_address" ->
+ (Json.Decode.succeed Tonkadur.Types.NextAllocableAddress)
+
+ "if_else" ->
+ (Json.Decode.map3
+ (\condition if_true if_false ->
+ (Tonkadur.Types.IfElse condition if_true if_false)
+ )
+ (Json.Decode.field "condition" (computation_decoder))
+ (Json.Decode.field "if_true" (computation_decoder))
+ (Json.Decode.field "if_false" (computation_decoder))
+ )
+
+ "last_choice_index" ->
+ (Json.Decode.succeed Tonkadur.Types.LastChoiceIndex)
+
+ "newline" -> (Json.Decode.succeed Tonkadur.Types.Newline)
+ "operation" ->
+ (Json.Decode.map3
+ (\op x maybe_y ->
+ (Tonkadur.Types.Operation
+ op
+ x
+ (
+ case maybe_y of
+ (Just y) -> y
+ Nothing ->
+ (Tonkadur.Types.Constant
+ "string"
+ "No second operand provided."
+ )
+ )
+ )
+ )
+ (Json.Decode.field "operator" (Json.Decode.string))
+ (Json.Decode.field "x" (computation_decoder))
+ (Json.Decode.maybe (Json.Decode.field "y" (computation_decoder)))
+ )
+
+ "relative_address" ->
+ (Json.Decode.map2
+ (\base extra -> (Tonkadur.Types.RelativeAddress base extra))
+ (Json.Decode.field "base" (computation_decoder))
+ (Json.Decode.field "extra" (computation_decoder))
+ )
+
+ "text" ->
+ (Json.Decode.map
+ (\computation -> (Tonkadur.Types.Text computation))
+ (Json.Decode.field
+ "content"
+ (Json.Decode.list (computation_decoder))
+ )
+ )
+
+ "value_of" ->
+ (Json.Decode.map
+ (\computation -> (Tonkadur.Types.ValueOf computation))
+ (Json.Decode.field "reference" (computation_decoder))
+ )
+
+ _ ->
+ (Json.Decode.map
+ (\params -> (Tonkadur.Types.ExtraComputation name params))
+ (Json.Decode.field "params"
+ (Json.Decode.list (computation_decoder))
+ )
+ )
+
+computation_decoder : (Json.Decode.Decoder Tonkadur.Types.Computation)
+computation_decoder =
+ (Json.Decode.andThen
+ (specific_computation_decoder)
+ (Json.Decode.field "category" (Json.Decode.string))
+ )
+
+---- INSTRUCTIONS --------------------------------------------------------------
+prompt_instruction_data_decoder : (
+ (Json.Decode.Decoder Tonkadur.Types.PromptInstructionData)
+ )
+prompt_instruction_data_decoder =
+ (Json.Decode.succeed
+ Tonkadur.Types.PromptInstructionData
+ -- min
+ |> (Json.Decode.Pipeline.required "min" (computation_decoder))
+
+ -- max
+ |> (Json.Decode.Pipeline.required "max" (computation_decoder))
+
+ -- address
+ |> (Json.Decode.Pipeline.required "target" (computation_decoder))
+
+ -- label
+ |> (Json.Decode.Pipeline.required "label" (computation_decoder))
+ )
+
+specific_instruction_decoder : (
+ String -> (Json.Decode.Decoder Tonkadur.Types.Instruction)
+ )
+specific_instruction_decoder name =
+ case name of
+ "add_event_option" ->
+ (Json.Decode.map2
+ (\oname params -> (Tonkadur.Types.AddEventOption oname params))
+ (Json.Decode.field "event" (Json.Decode.string))
+ (Json.Decode.field
+ "reference"
+ (Json.Decode.list (computation_decoder))
+ )
+ )
+
+ "add_text_option" ->
+ (Json.Decode.map
+ (\computation -> (Tonkadur.Types.AddTextOption computation))
+ (Json.Decode.field "label" (computation_decoder))
+ )
+
+ "assert" ->
+ (Json.Decode.map2
+ (\condition label -> (Tonkadur.Types.Assert condition label))
+ (Json.Decode.field "condition" (computation_decoder))
+ (Json.Decode.field "message" (computation_decoder))
+ )
+
+ "display" ->
+ (Json.Decode.map
+ (\computation -> (Tonkadur.Types.Display computation))
+ (Json.Decode.field "content" (computation_decoder))
+ )
+
+ "end" -> (Json.Decode.succeed Tonkadur.Types.End)
+ "initialize" ->
+ (Json.Decode.map2
+ (\type_name ref -> (Tonkadur.Types.Initialize type_name ref))
+ (Json.Decode.field "type" (Json.Decode.string))
+ (Json.Decode.field "reference" (computation_decoder))
+ )
+
+ "prompt_command" ->
+ (Json.Decode.map
+ (\data -> (Tonkadur.Types.PromptCommand data))
+ (prompt_instruction_data_decoder)
+ )
+
+ "prompt_integer" ->
+ (Json.Decode.map
+ (\data -> (Tonkadur.Types.PromptInteger data))
+ (prompt_instruction_data_decoder)
+ )
+
+ "prompt_string" ->
+ (Json.Decode.map
+ (\data -> (Tonkadur.Types.PromptString data))
+ (prompt_instruction_data_decoder)
+ )
+
+ "remove" ->
+ (Json.Decode.map
+ (\computation -> (Tonkadur.Types.Remove computation))
+ (Json.Decode.field "reference" (computation_decoder))
+ )
+
+ "resolve_choice" -> (Json.Decode.succeed Tonkadur.Types.ResolveChoice)
+ "set_pc" ->
+ (Json.Decode.map
+ (\computation -> (Tonkadur.Types.SetPC computation))
+ (Json.Decode.field "value" (computation_decoder))
+ )
+
+ "set_random" ->
+ (Json.Decode.map3
+ (\min max target -> (Tonkadur.Types.SetRandom min max target))
+ (Json.Decode.field "min" (computation_decoder))
+ (Json.Decode.field "max" (computation_decoder))
+ (Json.Decode.field "target" (computation_decoder))
+ )
+
+ "set_value" ->
+ (Json.Decode.map2
+ (\target value -> (Tonkadur.Types.Set target value))
+ (Json.Decode.field "reference" (computation_decoder))
+ (Json.Decode.field "value" (computation_decoder))
+ )
+
+ _ ->
+ (Json.Decode.map
+ (\params -> (Tonkadur.Types.ExtraInstruction name params))
+ (Json.Decode.field "params"
+ (Json.Decode.list (computation_decoder))
+ )
+ )
+
+instruction_decoder : (Json.Decode.Decoder Tonkadur.Types.Instruction)
+instruction_decoder =
+ (Json.Decode.andThen
+ (specific_instruction_decoder)
+ (Json.Decode.field "category" (Json.Decode.string))
+ )
+
+
+---- TYPES --------------------------------------------------------------------
+-- There's a slight issue: we're getting the type definitions before they're
+-- used, yes, but we're getting all the type definitions before we're able to
+-- use the previous results.
+-- To mitigate this issue, we first get type names for fields instead of values
+-- (the 'raw' decoder), then we generate the actual values.
+raw_user_type_decoder : (
+ (Json.Decode.Decoder (String, (Dict.Dict String String)))
+ )
+raw_user_type_decoder =
+ (Json.Decode.map2
+ (\name pair_list -> (name, (Dict.fromList pair_list)))
+ (Json.Decode.field "name" (Json.Decode.string))
+ (Json.Decode.field "fields"
+ (Json.Decode.list
+ (Json.Decode.map2
+ (\name line -> (name, line))
+ (Json.Decode.field "name" (Json.Decode.string))
+ (Json.Decode.field "type" (Json.Decode.string))
+ )
+ )
+ )
+ )
+
+user_types_decoder : (
+ (Json.Decode.Decoder (Dict.Dict String Tonkadur.Types.Value))
+ )
+user_types_decoder =
+ (Json.Decode.map
+ (\list_of_raw_types ->
+ (List.foldl
+ (\(name, fields) defined_types ->
+ (Dict.insert
+ name
+ (Tonkadur.Types.StructureValue
+ (Dict.map
+ (\field_name field_type_name ->
+ case
+ (Tonkadur.Types.maybe_get_default_primitive
+ field_type_name
+ )
+ of
+ (Just default) -> default
+ Nothing ->
+ case
+ (Dict.get field_type_name defined_types)
+ of
+ (Just default) -> default
+ Nothing ->
+ (Tonkadur.Types.StringValue
+ (
+ "Undefined type '"
+ ++ field_type_name
+ ++ "'"
+ )
+ )
+ )
+ fields
+ )
+ )
+ defined_types
+ )
+ )
+ (Dict.empty)
+ list_of_raw_types
+ )
+ )
+ (Json.Decode.list (raw_user_type_decoder))
+ )
+
+---- STATE ---------------------------------------------------------------------
+code_decoder : (Json.Decode.Decoder (Array.Array Tonkadur.Types.Instruction))
+code_decoder = (Json.Decode.array (instruction_decoder))
+
+sequences_decoder : (Json.Decode.Decoder (Dict.Dict String Int))
+sequences_decoder =
+ (Json.Decode.map
+ (\pair_list -> (Dict.fromList pair_list))
+ (Json.Decode.list
+ (Json.Decode.map2
+ (\name line -> (name, line))
+ (Json.Decode.field "name" (Json.Decode.string))
+ (Json.Decode.field "value" (Json.Decode.int))
+ )
+ )
+ )
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+decoder : (Json.Decode.Decoder Tonkadur.Types.State)
+decoder =
+ (Json.Decode.succeed
+ Tonkadur.Types.State
+ -- memory
+ |> (Json.Decode.Pipeline.hardcoded (Dict.empty))
+
+ -- user_types
+ |> (Json.Decode.Pipeline.optional
+ "structure_types"
+ (user_types_decoder)
+ (Dict.empty)
+ )
+
+ -- sequences
+ |> (Json.Decode.Pipeline.optional
+ "sequences"
+ (sequences_decoder)
+ (Dict.empty)
+ )
+
+ -- code
+ |> (Json.Decode.Pipeline.required "code" (code_decoder))
+
+ -- program_counter
+ |> (Json.Decode.Pipeline.hardcoded 0)
+
+ -- allocated_data
+ |> (Json.Decode.Pipeline.hardcoded 0)
+
+ -- last_choice_index
+ |> (Json.Decode.Pipeline.hardcoded 0)
+
+ -- available_options
+ |> (Json.Decode.Pipeline.hardcoded [])
+
+ -- memorized_target
+ |> (Json.Decode.Pipeline.hardcoded (Tonkadur.Types.PointerValue []))
+
+ -- last_instruction_effect
+ |> (Json.Decode.Pipeline.hardcoded Tonkadur.Types.MustContinue)
+
+ -- freed_addresses
+ |> (Json.Decode.Pipeline.hardcoded [])
+
+ -- random_seed
+ |> (Json.Decode.Pipeline.hardcoded (Random.initialSeed 42))
+ )