Reading choices

This commit is contained in:
2020-10-03 16:17:00 -06:00
parent c43f8e99f3
commit 1743d9c3f5
4 changed files with 78 additions and 3 deletions

View File

@@ -3,12 +3,15 @@ package hank;
import hiss.HTypes;
import hiss.CCInterp;
import hiss.StaticFiles;
import hiss.HissReader;
using hiss.HissTools;
class Story {
var teller: StoryTeller;
var interp: CCInterp;
var storyScript: String;
// Separate reader for Hiss expressions:
var reader: HissReader;
public function new(storyScript: String, storyTeller: StoryTeller) {
StaticFiles.compileWith("reader-macros.hiss");
@@ -18,9 +21,11 @@ class Story {
teller = storyTeller;
interp = new CCInterp();
reader = new HissReader(interp); // It references the same CCInterp but has its own readtable
interp.importFunction(storyTeller, storyTeller.handleOutput, "*handle-output*");
interp.importFunction(storyTeller, storyTeller.handleChoices, "*handle-choices*");
interp.importFunction(reader, reader.read, "hiss-read");
interp.load("hanklib.hiss");
}

View File

@@ -0,0 +1,16 @@
-> start
== end
Good choice.
== start
You have to make a choice.
* (label) A
-> start
+ {t} B
-> start
* C
-> end

View File

@@ -10,6 +10,17 @@
(cond
((string? part) part)))
(defun divert (target) (print (+ "Diverting to " target)))
(defstruct choice once-only depth label condition output chosen-count on-chosen)
(defvar *choices* [])
(defvar *labeled-choices* (dict))
(defmacro defchoice (&rest args)
"Define a new choice and return its id"
`(let (c (make-choice ,@args)
label (choice-label c)
id (length *choices*))
(print c)
(push! *choices* c)
(when label (dict-set! *labeled-choices* label c))
id))
(enable-continuations)
(defvar *choice-points* [])

View File

@@ -1,5 +1,7 @@
(def-reader-macro "->" (start stream)
`(funcall ,(read-symbol "" stream)))
// TODO don't just funcall, check the scope tree of divert targets (split by .)
// TODO diverts should quit when finished unless another -> starts a tunnel or tunnels back
(def-reader-macro "==" (start stream)
(let (knot-name
@@ -13,6 +15,47 @@
(eval (print `(defun ,knot-name () ,@knot-body (quit))))
nil))
(defun read-choice (start stream)
"will be called with start=nil for all choices following the first in a choice point"
(let (start-char
(or start (HStream:peek stream 1))
once-only
(case start-char
("*" t)
("+" nil))
depth
(+ (if start 1 0) (HStream:count-consecutive stream start-char))
label
(case
(begin
(HStream:drop-whitespace stream)
(HStream:peek stream 1))
("("
(trim (substring (first (HStream:take-until stream [")"])) 1))))
condition
(case
(begin
(HStream:drop-whitespace stream)
(HStream:peek stream 1))
("{"
(hiss-read "" (HStream:from-string (trim (substring (first (HStream:take-until stream ["}"])) 1)))))
(default t))
output
(read-output "" stream)
on-chosen
`(begin
,@(read-all (first (HStream:take-until stream [(* depth "*") (* depth "+") (+ (* depth "-") " ")] nil nil t)))))
(defchoice once-only depth label condition output 0 on-chosen)))
(defun read-choice-point (start stream)
// TODO
(read-choice start stream))
(set-macro-string "*" read-choice-point)
(set-macro-string "+" read-choice-point)
(defun read-output (start stream)
`(output ,(HStream:take-line stream "rl")))