summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2021-12-26 17:13:33 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2021-12-26 17:13:33 +0100
commit9c46df53ad401e060664aafe8fdfbcb9a3da5731 (patch)
treecbe3e412bc04e322ddab5ca52bdb776c63b3fdc2
Initial commit.
-rw-r--r--Makefile36
-rw-r--r--elm.json27
-rw-r--r--src/ElmModule/Init.elm18
-rw-r--r--src/ElmModule/Subscriptions.elm15
-rw-r--r--src/ElmModule/Update.elm23
-rw-r--r--src/ElmModule/View.elm26
-rw-r--r--src/Main.elm25
-rw-r--r--src/Struct/Event.elm19
-rw-r--r--src/Struct/Flags.elm43
-rw-r--r--src/Struct/Model.elm29
-rw-r--r--src/Struct/UI.elm24
-rw-r--r--src/Tonkadur/Compute.elm377
-rw-r--r--src/Tonkadur/Execute.elm301
-rw-r--r--src/Tonkadur/PlayerInput.elm85
-rw-r--r--src/Tonkadur/Types.elm268
15 files changed, 1316 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4fabb97
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,36 @@
+################################################################################
+## CONFIG ######################################################################
+################################################################################
+SRC_DIR ?= src
+WWW_DIR ?= www
+WWW_SCRIPT_DIR ?= $(WWW_DIR)/script
+
+ELM_CC ?= elm make
+
+MAIN_MODULE ?= $(SRC_DIR)/Main.elm
+
+################################################################################
+## MAKEFILE MAGIC ##############################################################
+################################################################################
+SUB_MODULES = $(shell find $(SRC_DIR) -type f | grep "elm$$")
+
+################################################################################
+## SANITY CHECKS ###############################################################
+################################################################################
+
+################################################################################
+## TARGET RULES ################################################################
+################################################################################
+build: $(WWW_SCRIPT_DIR)/main.js
+
+clean:
+ rm -f $(WWW_SCRIPT_DIR)/main.js
+
+reset:
+ rm -rf elm-stuff
+
+################################################################################
+## INTERNAL RULES ##############################################################
+################################################################################
+$(WWW_SCRIPT_DIR)/main.js: $(MAIN_MODULE) $(SUB_MODULES)
+ $(ELM_CC) $(MAIN_MODULE) --output $@
diff --git a/elm.json b/elm.json
new file mode 100644
index 0000000..923a948
--- /dev/null
+++ b/elm.json
@@ -0,0 +1,27 @@
+{
+ "type": "application",
+ "source-directories": [
+ "src"
+ ],
+ "elm-version": "0.19.1",
+ "dependencies": {
+ "direct": {
+ "elm/browser": "1.0.1",
+ "elm/core": "1.0.2",
+ "elm/html": "1.0.0",
+ "elm/http": "2.0.0",
+ "elm/json": "1.1.2",
+ "elm/time": "1.0.0",
+ "elm/url": "1.0.0"
+ },
+ "indirect": {
+ "elm/bytes": "1.0.7",
+ "elm/file": "1.0.1",
+ "elm/virtual-dom": "1.0.2"
+ }
+ },
+ "test-dependencies": {
+ "direct": {},
+ "indirect": {}
+ }
+}
diff --git a/src/ElmModule/Init.elm b/src/ElmModule/Init.elm
new file mode 100644
index 0000000..9af3cce
--- /dev/null
+++ b/src/ElmModule/Init.elm
@@ -0,0 +1,18 @@
+module ElmModule.Init exposing (init)
+
+-- Local Module ----------------------------------------------------------------
+import Struct.Flags
+import Struct.Event
+import Struct.Model
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+init : Struct.Flags.Type -> (Struct.Model.Type, (Cmd Struct.Event.Type))
+init flags =
+ -- TODO: read flags and request story.
+ (model, Cmd.none)
diff --git a/src/ElmModule/Subscriptions.elm b/src/ElmModule/Subscriptions.elm
new file mode 100644
index 0000000..c2b9fbe
--- /dev/null
+++ b/src/ElmModule/Subscriptions.elm
@@ -0,0 +1,15 @@
+module ElmModule.Subscriptions exposing (..)
+
+-- Local Module ----------------------------------------------------------------
+import Struct.Model
+import Struct.Event
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+subscriptions : Struct.Model.Type -> (Sub Struct.Event.Type)
+subscriptions model = Sub.none
diff --git a/src/ElmModule/Update.elm b/src/ElmModule/Update.elm
new file mode 100644
index 0000000..a4b827a
--- /dev/null
+++ b/src/ElmModule/Update.elm
@@ -0,0 +1,23 @@
+module ElmModule.Update exposing (update)
+
+-- Elm -------------------------------------------------------------------------
+
+-- Local Module ----------------------------------------------------------------
+import Struct.Event
+import Struct.Model
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+update : (
+ Struct.Event.Type ->
+ Struct.Model.Type ->
+ (Struct.Model.Type, (Cmd Struct.Event.Type))
+ )
+update event model =
+ case event of
+ Struct.Event.None -> (model, Cmd.none)
diff --git a/src/ElmModule/View.elm b/src/ElmModule/View.elm
new file mode 100644
index 0000000..fb99b89
--- /dev/null
+++ b/src/ElmModule/View.elm
@@ -0,0 +1,26 @@
+module ElmModule.View exposing (view)
+
+-- Elm -------------------------------------------------------------------------
+import Html
+import Html.Attributes
+
+-- Local Module ----------------------------------------------------------------
+import Struct.Event
+import Struct.Model
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+view : Struct.Model.Type -> (Html.Html Struct.Event.Type)
+view model =
+ (Html.div
+ [
+ (Html.Attributes.class "fullscreen-module")
+ ]
+ [
+ ]
+ )
diff --git a/src/Main.elm b/src/Main.elm
new file mode 100644
index 0000000..0f8f61a
--- /dev/null
+++ b/src/Main.elm
@@ -0,0 +1,25 @@
+module Main exposing (main)
+
+-- Elm ------------------------------------------------------------------------
+import Browser
+
+-- Local Module ----------------------------------------------------------------
+import ElmModule.Init
+import ElmModule.Subscriptions
+import ElmModule.View
+import ElmModule.Update
+
+import Struct.Flags
+import Struct.Model
+import Struct.Event
+
+main : (Program Shared.Struct.Flags.Type Struct.Model.Type Struct.Event.Type)
+main =
+ (Browser.element
+ {
+ init = ElmModule.Init.init,
+ view = ElmModule.View.view,
+ update = ElmModule.Update.update,
+ subscriptions = ElmModule.Subscriptions.subscriptions
+ }
+ )
diff --git a/src/Struct/Event.elm b/src/Struct/Event.elm
new file mode 100644
index 0000000..78079d2
--- /dev/null
+++ b/src/Struct/Event.elm
@@ -0,0 +1,19 @@
+module Struct.Event exposing (..)
+
+-- Elm -------------------------------------------------------------------------
+
+-- Local Module ----------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+type Type =
+ EventType0
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
diff --git a/src/Struct/Flags.elm b/src/Struct/Flags.elm
new file mode 100644
index 0000000..43fc7c2
--- /dev/null
+++ b/src/Struct/Flags.elm
@@ -0,0 +1,43 @@
+module Struct.Flags exposing
+ (
+ Type,
+ force_get_parameter,
+ get_parameters_as_url
+ )
+
+-- Elm -------------------------------------------------------------------------
+import List
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+type alias Type =
+ {
+ url_parameters : (List (List String))
+ }
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+parameter_as_url : (List String) -> String
+parameter_as_url parameter =
+ case parameter of
+ [name, value] -> (name ++ "=" ++ value)
+ _ -> ""
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+force_get_parameter : String -> Type -> String
+force_get_parameter parameter flags = ""
+ -- TODO: implement using Tactician Online's, but without Shared.Util.List
+
+get_parameters_as_url : Type -> String
+get_parameters_as_url flags =
+ (List.foldl
+ (\parameter -> \current_parameters ->
+ (current_parameters ++ "&" ++ (parameter_as_url parameter))
+ )
+ ""
+ flags.url_parameters
+ )
diff --git a/src/Struct/Model.elm b/src/Struct/Model.elm
new file mode 100644
index 0000000..a11db5c
--- /dev/null
+++ b/src/Struct/Model.elm
@@ -0,0 +1,29 @@
+module Struct.Model exposing
+ (
+ Type
+ )
+
+-- Elm -------------------------------------------------------------------------
+
+-- Tonkadur --------------------------------------------------------------------
+import Tonkadur.Types
+
+-- Local Module ----------------------------------------------------------------
+import Struct.UI
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+type alias Type =
+ {
+ tonkadur : Tonkadur.Types.State,
+ ui : Struct.UI.Type
+ }
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
diff --git a/src/Struct/UI.elm b/src/Struct/UI.elm
new file mode 100644
index 0000000..53348f6
--- /dev/null
+++ b/src/Struct/UI.elm
@@ -0,0 +1,24 @@
+module Struct.UI exposing
+ (
+ Type
+ )
+
+-- Elm -------------------------------------------------------------------------
+import List
+import String
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+type alias Type =
+ {
+ displayed_options : (List String)
+ }
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
diff --git a/src/Tonkadur/Compute.elm b/src/Tonkadur/Compute.elm
new file mode 100644
index 0000000..489ab3b
--- /dev/null
+++ b/src/Tonkadur/Compute.elm
@@ -0,0 +1,377 @@
+module Tonkadur.Compute exposing (compute)
+
+-- Elm -------------------------------------------------------------------------
+import Dict
+import List
+
+-- Tonkadur --------------------------------------------------------------------
+import Tonkadur.Types
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+add_text_effect : (
+ Tonkadur.Types.State ->
+ String ->
+ (List Tonkadur.Types.Computation) ->
+ Tonkadur.Types.Value
+ )
+add_text_effect state name parameters content =
+ (TextValue
+ (AugmentedText
+ {
+ content = (List.map (compute state) content),
+ effect_name = name,
+ effect_parameters = parameters
+ }
+ )
+ )
+
+address : (
+ Tonkadur.Types.State ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Value
+ )
+address state param =
+ case (compute state param) of
+ (PointerValue address) -> (PointerValue address)
+ (StringValue singleton) -> (PointerValue (List.singleton singleton))
+ _ -> (PointerValue [])
+
+unsupported_cast : String -> String -> Tonkadur.Types.Value
+unsupported_cast from to =
+ (StringValue ("Unsupported cast from " + from + " to " + to + "."))
+
+cast : (
+ Tonkadur.Types.State ->
+ String ->
+ String ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Value
+ )
+cast state from to param =
+ case (compute state param) of
+ (BoolValue bool) ->
+ case to of
+ "string" ->
+ if bool
+ then (StringValue "true")
+ else (StringValue "false")
+
+ "text" ->
+ if bool
+ then (TextValue (StringText "true"))
+ else (TextValue (StringText "false"))
+
+ "bool" -> (BoolValue bool)
+ _ -> (unsupported_cast from to)
+
+ (FloatValue float) ->
+ case to of
+ "string" -> (StringValue (String.fromFloat float))
+ "text" -> (TextValue (StringText (String.fromFloat float)))
+ "int" -> (IntValue (Math.floor float))
+ "float" -> (FloatValue float)
+ _ -> (unsupported_cast from to)
+
+ (IntValue int) ->
+ case to of
+ "string" -> (StringValue (String.fromInt int))
+ "text" -> (TextValue (StringText (String.fromInt int)))
+ "float" -> (FloatValue (Math.toFloat int))
+ "int" -> (IntValue int)
+ _ -> (unsupported_cast from to)
+
+ (TextValue text) ->
+ let as_string = (Tonkadur.Types.value_to_string (TextValue text)) in
+ case to of
+ "string" -> (StringValue as_string)
+ "float" ->
+ case (String.toFloat as_string) of
+ Nothing -> (unsupported_cast from to)
+ (Just result) -> (FloatValue result)
+
+ "int" ->
+ case (String.toInt as_string) of
+ Nothing -> (unsupported_cast from to)
+ (Just result) -> (IntValue result)
+
+ "text" -> (TextValue text)
+ _ -> (unsupported_cast from to)
+
+ (StringValue string) ->
+ case to of
+ "string" -> (StringValue string)
+ "float" ->
+ case (String.fromFloat string) of
+ Nothing -> (unsupported_cast from to)
+ (Just result) -> (FloatValue result)
+
+ "int" ->
+ case (String.toInt string) of
+ Nothing -> (unsupported_cast from to)
+ (Just result) -> (IntValue result)
+
+ "text" -> (TextValue (StringText string))
+
+ _ -> (unsupported_cast from to)
+
+ _ -> (unsupported_cast from to)
+
+constant : (
+ Tonkadur.Types.State ->
+ String ->
+ String ->
+ Tonkadur.Types.Value
+ )
+constant state target_type as_string =
+ (cast state "string" target_type as_string)
+
+extra_computation : (
+ Tonkadur.Types.State ->
+ String ->
+ (List Tonkadur.Types.Computation) ->
+ Tonkadur.Types.Value
+ )
+extra_computation state name parameters =
+ case name of
+ _ -> (StringValue ("Unsupported extra computation '" + name + "'"))
+
+if_else : (
+ Tonkadur.Types.State ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Value
+ )
+if_else state condition if_true if_false =
+ if (WyrdType.to_boolean (compute state condition))
+ then (compute state if_true)
+ else (compute state if_false)
+
+last_choice_index : Tonkadur.Types.State -> Tonkadur.Types.Value
+last_choice_index state = (IntValue state.last_choice_index)
+
+newline : Tonkadur.Types.State -> Tonkadur.Types.Value
+newline state = (TextValue Newline)
+
+next_allocable_address : Tonkadur.Types.State -> Tonkadur.Types.Value
+next_allocable_address state = (IntValue state.next_allocable_address)
+
+operation : (
+ Tonkadur.Types.State ->
+ String ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Value
+ )
+operation state name param0 param1 =
+ let
+ value0 = (compute state param0)
+ value1 = (compute state param1)
+ in
+ case name of
+ "divide" ->
+ case value0 of
+ (IntValue val) ->
+ (IntValue (val // (Tonkadur.Types.value_to_int value1)))
+
+ _ ->
+ (FloatValue
+ (
+ (Tonkadur.Types.value_to_float value0)
+ / (Tonkadur.Types.value_to_float value1)
+ )
+ )
+
+ "minus" ->
+ case value0 of
+ (IntValue val) ->
+ (IntValue (val - (Tonkadur.Types.value_to_int value1)))
+
+ _ ->
+ (FloatValue
+ (
+ (Tonkadur.Types.value_to_float value0)
+ - (Tonkadur.Types.value_to_float value1)
+ )
+ )
+
+ "modulo" ->
+ (IntValue
+ (modBy
+ (Tonkadur.Types.value_to_int value0)
+ (Tonkadur.Types.value_to_int value1)
+ )
+ )
+
+ "plus" ->
+ case value0 of
+ (IntValue val) ->
+ (IntValue (val + (Tonkadur.Types.value_to_int value1)))
+
+ _ ->
+ (FloatValue
+ (
+ (Tonkadur.Types.value_to_float value0)
+ + (Tonkadur.Types.value_to_float value1)
+ )
+ )
+
+ "power" ->
+ case value0 of
+ (IntValue val) ->
+ (IntValue (val ^ (Tonkadur.Types.value_to_int value1)))
+
+ _ ->
+ (FloatValue
+ (
+ (Tonkadur.Types.value_to_float value0)
+ ^ (Tonkadur.Types.value_to_float value1)
+ )
+ )
+
+ "times" ->
+ case value0 of
+ (IntValue val) ->
+ (IntValue (val * (Tonkadur.Types.value_to_int value1)))
+
+ _ ->
+ (FloatValue
+ (
+ (Tonkadur.Types.value_to_float value0)
+ * (Tonkadur.Types.value_to_float value1)
+ )
+ )
+
+ "and" ->
+ (BoolValue
+ (and
+ (Tonkadur.Types.value_to_bool value0)
+ (Tonkadur.Types.value_to_bool value1)
+ )
+ )
+
+ "not" -> (BoolValue (not (Tonkadur.Types.value_to_bool value0)))
+
+ "less_than" ->
+ case value0 of
+ (BoolValue bool) ->
+ (and (Tonkadur.Types.value_to_bool value1) (not boot))
+
+ (FloatValue float) ->
+ (BoolValue (float < (Tonkadur.Types.value_to_float value1)))
+
+ (IntValue int) ->
+ (BoolValue (int < (Tonkadur.Types.value_to_int value1)))
+
+ (StringValue str) ->
+ (BoolValue (str < (Tonkadur.Types.value_to_string value1)))
+
+ (PointerValue ptr) ->
+ (BoolValue
+ (
+ (Tonkadur.Types.compare_pointers
+ ptr
+ (Tonadur.Wyrd.value_to_dict value1)
+ )
+ > 0
+ )
+ )
+
+ "equals" -> (value0 == value1)
+
+relative_address : (
+ Tonkadur.Types.State ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Value
+ )
+relative_address state base extra =
+ (PointerValue
+ (List.append
+ (Tonkadur.Types.value_to_list (compute state base))
+ (Tonkadur.Types.value_to_list (compute state extra))
+ )
+ )
+
+size : (
+ Tonkadur.Types.State ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Value
+ )
+size state computation =
+ (IntValue
+ (Dict.size (Tonkadur.Types.value_to_dict (compute state computation)))
+ )
+
+
+text : (
+ Tonkadur.Types.State ->
+ (List Tonkadur.Types.Computation) ->
+ Tonkadur.Types.Value
+ )
+text state content =
+ (List.foldl
+ (\addition result ->
+ (TextValue
+ (Tonkadur.Types.append_text_content
+ (Tonkadur.Types.value_to_text result)
+ (Tonkadur.Types.value_to_text (compute state addition))
+ )
+ )
+ )
+ (TextValue (Tonkadur.Types.default_text_data))
+ content
+ )
+
+value_of : (
+ Tonkadur.Types.State ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Value
+ )
+value_of state computation =
+ (List.foldl
+ (\next_step object ->
+ case (Dict.get next_step (Tonkadur.Types.value_to_dict object)) of
+ Nothing -> (StringValue "Segmentation Fault (incorrect address)")
+ (Just value) -> value
+ )
+ (StructureValue state.memory)
+ (Tonkadur.Types.value_to_list (compute state computation))
+ )
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+compute : (
+ Tonkadur.Types.State ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Value
+ )
+compute state computation =
+ case computation of
+ (AddTextEffect effect_name effect_parameters content) ->
+ (add_text_effect state effect_name effect_parameters content)
+
+ (Address param) -> (address state param)
+ (Cast from to value) -> (cast state from to value)
+ (Constant true_type as_string) -> (constant state true_type as_string)
+ (ExtraComputation name parameters) ->
+ (extra_computation state name parameters)
+
+ (IfElse condition if_true if_false) ->
+ (if_else state condition if_true if_false)
+
+ LastChoiceIndex -> (last_choice_index state)
+ Newline -> (newline state)
+ NextAllocableAddress -> (next_allocable_address state)
+ (Operation name arg_0 arg_1) -> (operation state name arg_0 arg_1)
+ (RelativeAddress base extra) -> (relative_address state base extra)
+ (Size value) -> (size state value)
+ (Text content) -> (text state content)
+ (ValueOf address) -> (value_of state address)
diff --git a/src/Tonkadur/Execute.elm b/src/Tonkadur/Execute.elm
new file mode 100644
index 0000000..98eb680
--- /dev/null
+++ b/src/Tonkadur/Execute.elm
@@ -0,0 +1,301 @@
+module Tonkadur.Execute exposing (execute)
+
+-- Elm -------------------------------------------------------------------------
+import Dict
+import List
+
+-- Tonkadur --------------------------------------------------------------------
+import Tonkadur.Types
+
+import Tonkadur.Compute
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+increment_program_counter : Tonkadur.Types.State -> Tonkadur.Types.State
+increment_program_counter state =
+ {state | program_counter = program_counter + 1}
+
+---- INSTRUCTIONS --------------------------------------------------------------
+add_event_option : (
+ String ->
+ (List Tonkadur.Types.Computation) ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+add_event_option name parameters state =
+ (Tonkadur.Types.append_option
+ (Event name (List.map (Tonkadur.Compute.compute state) parameters))
+ state
+ )
+
+add_text_option : (
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+add_text_option label state =
+ (Tonkadur.Types.append_option
+ (Choice (Tonkadur.Compute.compute label state))
+ state
+ )
+
+assert : (
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+assert condition label state =
+ if (Tonkadur.Types.value_to_bool (Tonkadur.Compute.compute state condition))
+ then
+ -- TODO: some special error report
+ state
+ else state
+
+display : (
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+)
+display label state =
+ -- TODO: where do we put displayed values?
+ state
+
+end : Tonkadur.Types.State -> Tonkadur.Types.State
+end state =
+ -- TODO: what do we do with this?
+ state
+
+extra_instruction : (
+ String ->
+ (List Tonkadur.Types.Computation) ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+extra_instruction name parameters state =
+ -- No extra instruction supported.
+ -- TODO: error report.
+
+initialize : (
+ String ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+initialize type_name address state =
+ {state |
+ memory =
+ (Tonkadur.Types.apply_at_address
+ (Tonkadur.Types.value_to_list
+ (Tonkadur.Compute.compute state address)
+ )
+ (\last_addr dict ->
+ (Dict.insert
+ last_addr
+ (Tonkadur.Types.get_default state type_name)
+ dict
+ )
+ )
+ state.memory
+ )
+ }
+
+prompt_command : (
+ Tonkadur.Types.PromptInstructionData ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+prompt_command prompt_data state =
+ {state |
+ memorized_target = (Tonkadur.Compute.compute state prompt_data.address),
+ last_instruction_effect =
+ (PromptCommand
+ (Tonkadur.Compute.compute state prompt_data.min)
+ (Tonkadur.Compute.compute state prompt_data.max)
+ (Tonkadur.Compute.compute state prompt_data.label)
+ )
+ }
+
+prompt_string : (
+ Tonkadur.Types.PromptInstructionData ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+prompt_string prompt_data state =
+ {state |
+ memorized_target = (Tonkadur.Compute.compute state prompt_data.address),
+ last_instruction_effect =
+ (PromptString
+ (Tonkadur.Compute.compute state prompt_data.min)
+ (Tonkadur.Compute.compute state prompt_data.max)
+ (Tonkadur.Compute.compute state prompt_data.label)
+ )
+ }
+
+prompt_integer : (
+ Tonkadur.Types.PromptInstructionData ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+prompt_integer prompt_data state =
+ {state |
+ memorized_target = (Tonkadur.Compute.compute state prompt_data.address),
+ last_instruction_effect =
+ (PromptInteger
+ (Tonkadur.Compute.compute state prompt_data.min)
+ (Tonkadur.Compute.compute state prompt_data.max)
+ (Tonkadur.Compute.compute state prompt_data.label)
+ )
+ }
+
+remove : (
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+remove address state =
+ {state |
+ memory =
+ (Tonkadur.Types.apply_at_address
+ (Tonkadur.Types.value_to_list
+ (Tonkadur.Compute.compute state address)
+ )
+ (\last_addr dict -> (Dict.remove last_addr dict))
+ state.memory
+ )
+ }
+
+resolve_choice : Tonkadur.Types.State -> Tonkadur.Types.State
+resolve_choice state =
+ {state | last_instruction_effect = PromptChoice}
+
+set_pc : (
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+)
+set_pc value state =
+ {state |
+ program_counter =
+ (Tonkadur.Types.value_to_int
+ (Tonkadur.Compute.compute state value)
+ )
+ }
+
+set_random : (
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+)
+set_random address min max state =
+ let
+ (value, next_random_seed) =
+ (Random.step
+ (Random.int
+ (Tonkadur.Types.value_to_int
+ (Tonkadur.Compute.compute state min)
+ (Tonkadur.Compute.compute state max)
+ )
+ )
+ state.random_seed
+ )
+ in
+ {state |
+ memory =
+ (Tonkadur.Types.apply_at_address
+ (Tonkadur.Types.value_to_list
+ (Tonkadur.Compute.compute state address)
+ )
+ (\last_addr dict -> (Dict.insert last_addr (IntValue value) dict))
+ state.memory
+ ),
+
+ random_seed = next_random_seed
+ }
+
+set : (
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.Computation ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+)
+set address value state =
+ {state |
+ memory =
+ (Tonkadur.Types.apply_at_address
+ (Tonkadur.Types.value_to_list
+ (Tonkadur.Compute.compute state address)
+ )
+ (\last_addr dict ->
+ (Dict.insert
+ last_addr
+ (Tonkadur.Compute.compute state value)
+ dict
+ )
+ )
+ state.memory
+ )
+ }
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+execute : (
+ Tonkadur.Types.Instruction ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State ->
+ )
+execute instruction state =
+ let new_state = {state | last_instruction_effect = Continue} in
+ case instruction of
+ (AddEventOption name parameters) ->
+ (increment_program_counter
+ (add_event_option name parameters new_state)
+ )
+
+ (AddTextOption label) ->
+ (increment_program_counter
+ (add_text_option name parameters new_state)
+ )
+
+ (Assert condition label) ->
+ (increment_program_counter
+ (assert condition label new_state)
+ )
+
+ (Display label) ->
+ (increment_program_counter (display label new_state))
+
+ End -> (end new_state)
+ (ExtraInstruction name parameters) ->
+ (extra_instruction name parameters new_state)
+
+ (Initialize type_name address) ->
+ (increment_program_counter
+ (initialize type_name address new_state)
+ )
+ (PromptCommand prompt_data) ->
+ (increment_program_counter (prompt_command prompt_data new_state))
+
+ (PromptInteger prompt_data) ->
+ (increment_program_counter (prompt_integer prompt_data new_state))
+
+ (PromptString prompt_data) ->
+ (increment_program_counter (prompt_string prompt_data new_state))
+
+ (Remove address) -> (increment_program_counter (remove address new_state))
+ ResolveChoice -> (increment_program_counter (resolve_choice new_state))
+ (SetPC value) -> (set_pc value new_state)
+ (SetRandom address min max) ->
+ (increment_program_counter (set_random address min max new_state))
+
+ (Set address value) ->
+ (increment_program_counter (set address value new_state))
+
diff --git a/src/Tonkadur/PlayerInput.elm b/src/Tonkadur/PlayerInput.elm
new file mode 100644
index 0000000..facf9e5
--- /dev/null
+++ b/src/Tonkadur/PlayerInput.elm
@@ -0,0 +1,85 @@
+module Tonkadur.PlayerInput exposing (..)
+
+-- Elm -------------------------------------------------------------------------
+import Dict
+import List
+
+-- Tonkadur --------------------------------------------------------------------
+import Tonkadur.Types
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+select_choice : Int -> Tonkadur.Types.State -> Tonkadur.Types.State
+select_choice index state = {state | last_choice_index = index}
+
+input_string : String -> Tonkadur.Types.State -> Tonkadur.Types.State
+input_string string state =
+ {state |
+ memory =
+ (Tonkadur.Types.apply_at_address
+ (Tonkadur.Types.value_to_address state.memorized_target)
+ (\last_address dict ->
+ (Dict.insert last_address (StringValue string) dict)
+ )
+ state.memory
+ )
+ }
+
+input_int : Int -> Tonkadur.Types.State -> Tonkadur.Types.State
+input_int int state =
+ {state |
+ memory =
+ (Tonkadur.Types.apply_at_address
+ (Tonkadur.Types.value_to_address state.memorized_target)
+ (\last_address dict ->
+ (Dict.insert last_address (IntValue int) dict)
+ )
+ state.memory
+ )
+ }
+
+input_command : (
+ (List String) ->
+ Tonkadur.Types.State ->
+ Tonkadur.Types.State
+ )
+input_command commands state =
+ {state |
+ memory =
+ (Tonkadur.Types.apply_at_address
+ (Tonkadur.Types.value_to_address state.memorized_target)
+ (\last_address dict ->
+ (Dict.insert
+ last_address
+ (ListValue
+ (Dict.fromList
+ (List.indexedMap
+ (\index value ->
+ (
+ (
+ case (String.fromInt index) of
+ (Just i) -> i
+ Nothing -> "invalid_index"
+ ),
+ value
+ )
+ )
+ commands
+ )
+ )
+ )
+ dict
+ )
+ )
+ state.memory
+ )
+ }
diff --git a/src/Tonkadur/Types.elm b/src/Tonkadur/Types.elm
new file mode 100644
index 0000000..9df1df7
--- /dev/null
+++ b/src/Tonkadur/Types.elm
@@ -0,0 +1,268 @@
+module Tonkadur.Types exposing (..)
+
+-- Elm -------------------------------------------------------------------------
+import Dict
+import List
+
+--------------------------------------------------------------------------------
+-- TYPES -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+type alias TextData =
+ {
+ content : (List RichText),
+ effect_name : String,
+ effect_parameters : (List Value)
+ }
+
+
+type RichText =
+ StringText String
+ | AugmentedText TextData
+ | NewlineText
+
+type Value =
+ BoolValue Bool
+ | FloatValue Float
+ | IntValue Int
+ | TextValue RichText
+ | StringValue String
+ | ListValue (Dict.Dict String Value)
+ | PointerValue (List String)
+ | StructureValue (Dict.Dict String Value)
+
+type Option =
+ Choice RichText
+ | Event (String, (List Value))
+
+type Computation =
+ AddTextEffect (String, (List Computation), (List Computation))
+ | Address Computation
+ | Cast (String, String, Computation)
+ | Constant (String, String)
+ | ExtraComputation (String, (List Computation))
+ | IfElse (Computation, Computation, Computation)
+ | LastChoiceIndex
+ | Newline
+ | NextAllocableAddress
+ | Operation (String, Computation, Computation)
+ | RelativeAddress (Computation, Computation)
+ | Size Computation
+ | Text (List Computation)
+ | ValueOf Computation
+
+type alias PromptInstructionData =
+ {
+ min : Computation,
+ max : Computation,
+ address : Computation,
+ label : Computation
+ }
+type Instruction =
+ AddEventOption (String, (List Computation))
+ | AddTextOption Computation
+ | Assert (Computation, Computation)
+ | Display Computation
+ | End
+ | ExtraInstruction (String, (List Computation))
+ | Initialize (String, Computation)
+ | PromptCommand PromptInstructionData
+ | PromptInteger PromptInstructionData
+ | PromptString PromptInstructionData
+ | Remove Computation
+ | ResolveChoice
+ | SetPC Computation
+ | SetRandom (Computation, Computation, Computation)
+ | Set (Computation, Computation)
+
+type InstructionEffect =
+ MustContinue
+ | MustEnd
+ | MustPromptCommand (Value, Value, Value)
+ | MustPromptInteger (Value, Value, Value)
+ | MustPromptString (Value, Value, Value)
+ | MustPromptChoice
+ | MustDisplay Value
+ | MustDisplayError Value
+ | MustExtraEffect (String, (List Value))
+
+type alias State =
+ {
+ memory : (Dict.Dict String Value),
+ user_types : (Dict.Dict String Value),
+ sequences : (Dict.Dict String Int),
+ code : (List Instruction),
+ program_counter : Int,
+ allocated_data : Int,
+ last_choice_index : Int,
+ available_options : (List Option),
+ memorized_target : Value,
+
+ last_instruction_effect : InstructionEffect
+ }
+
+--------------------------------------------------------------------------------
+-- LOCAL -----------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- EXPORTED --------------------------------------------------------------------
+--------------------------------------------------------------------------------
+value_to_bool : Value -> Bool
+value_to_bool value =
+ case value of
+ (BoolValue result) -> result
+ _ -> False
+
+value_to_float : Value -> Float
+value_to_float value =
+ case value of
+ (FloatValue result) -> result
+ _ -> 0.0
+
+value_to_int : Value -> Int
+value_to_int value =
+ case value of
+ (IntValue result) -> result
+ _ -> 0
+
+value_to_text_or_string : Value -> RichText
+value_to_text_or_string value =
+ case value of
+ (TextValue result) -> result
+ (StringValue string) -> (StringText string)
+ _ -> (StringText "")
+
+value_to_string : Value -> String
+value_to_string value =
+ case value of
+ (StringValue result) -> result
+ (TextValue text) ->
+ case text of
+ (StringText result) -> result
+ (AugmentedText rich_text) ->
+ (String.concat
+ (List.map (value_to_string) rich_text.content)
+ )
+
+ NewlineText -> "\n"
+
+ _ -> (StringText "")
+
+value_to_dict : Value -> (Dict.Dict String Value)
+value_to_dict value =
+ case value of
+ (StructureValue dict) -> dict
+ (ListValue dict) -> dict
+ _ -> (Dict.empty)
+
+value_to_address : Value -> (List String)
+value_to_address value =
+ case value of
+ (PointerValue result) -> result
+ _ -> []
+
+no_text_effect : String
+no_text_effect = ""
+
+append_text_content : RichText -> RichText -> RichText
+append_text_content base addition =
+ case base of
+ (AugmentedText text_data) ->
+ case addition of
+ (AugmentedText other_text_data) ->
+ -- Optimize text to avoid increasing depth if no new effect is
+ -- introduced.
+ if (other_text_data.effect_name == (no_text_effect))
+ then
+ (AugmentedText
+ {text_data |
+ content =
+ (List.append base.content other_text_data.content)
+ }
+ )
+ else
+ (AugmentedText
+ {text_data |
+ content =
+ (List.append
+ base.content
+ (List.singleton other_text_data)
+ )
+ }
+ )
+
+ other ->
+ (AugmentedText
+ {text_data |
+ content =
+ (List.append base.content (List.singleton other))
+ }
+ )
+
+ non_augmented_text_data ->
+ (append_text_content
+ (append_text_content (AugmentedText (default_text_data)) base)
+ addition
+ )
+
+default_text_data : TextData
+default_text_data =
+ {
+ effect_name = (no_text_effect),
+ effect_parameters = [],
+ content = []
+ }
+
+append_option : Option -> State -> State
+append_option option state =
+ {state |
+ available_options =
+ (List.append state.available_options (List.singleton option))
+ }
+
+get_default : State -> String -> Value
+get_default state type_name =
+ case type_name of
+ "bool" -> (BoolValue False)
+ "float" -> (FloatValue 0.0)
+ "int" -> (IntValue 0)
+ "text" -> (TextValue (StringText ""))
+ "string" -> (StringValue "")
+ "list" -> (ListValue (Dict.empty))
+ "ptr" -> (PointerValue [])
+ other ->
+ case (Dict.get other state.user_types) of
+ (Just default) -> default
+ Nothing -> (StringValue ("Unknown type '" + other + "'"))
+
+apply_at_address : (
+ (List String) ->
+ (
+ String ->
+ (Dict.Dict String Value) ->
+ (Dict.Dict String Value)
+ ) ->
+ (Dict.Dict String Value) ->
+ (Dict.Dict String Value)
+ )
+apply_at_address address fun memory =
+ case address of
+ [] -> memory
+ (last_element :: []) -> (fun last_element memory)
+ (next_element :: next_address) ->
+ (Dict.update
+ next_element
+ (\maybe_value ->
+ case maybe_value of
+ (Just value) ->
+ (Just
+ (apply_at_address
+ next_address
+ fun
+ (value_to_dict value)
+ )
+ )
+
+ Nothing -> Nothing
+ )
+ )