go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

commit bb6a692840a0ace15a90f40a617e8892108ad0a9
parent e0dd3c47423d36bdf3d77a52e597c9c4e20730d0
Author: lash <dev@holbrook.no>
Date:   Mon,  1 May 2023 19:14:34 +0100

Embed remaining readme content into texinfo docs

Diffstat:
MMakefile | 11++++++++++-
Adoc/texinfo/dev.texi | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adoc/texinfo/engine.texi | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/texinfo/index.texi | 3+++
Adoc/texinfo/language.texi | 16++++++++++++++++
Mdoc/texinfo/overview.texi | 5+++++
Mdoc/texinfo/signals.texi | 3++-
Adoc/texinfo/tools.texi | 4++++
8 files changed, 271 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,4 +1,13 @@ -all: profile session helloworld validate +all: bin examples doc + +examples: profile session helloworld validate + +bin: + mkdir -p build + go build -o build/interactive ./dev/interactive + go build -o build/gendata ./dev/gendata + go build -o build/asm ./dev/asm + go build -o build/disasm ./dev/disasm profile: make -C examples/profile diff --git a/doc/texinfo/dev.texi b/doc/texinfo/dev.texi @@ -0,0 +1,167 @@ +@node dev +@chapter Development + + +@section Code repository structure + +@table @code +@item asm +Assembly parser and compiler. +@item cache +Holds and manages all loaded content. +@item engine +Outermost interface. Orchestrates execution of bytecode against input. +@item lang +Validation and specification of language context. +@item logging +Logging interface and build tags for loglevels. +@item persist +Interface and reference implementation of `state` and `cache` persistence across asynchronous vm executions. +@item render +Renders menu and templates, and enforces output size constraints. +@item resource +Retrieves data and bytecode from external symbols, and retrieves templates. +@item state +Holds the bytecode buffer, error states and navigation states. +@item vm +Defines instructions, and applies transformations according to the instructions. +@end table + + +@section Logging + +Loglevels are set at compile-time using the following build tags: + +@itemize +@item @code{lognone} +@item @code{logerror} +@item @code{logwarn} +@item @code{loginfo} +@item @code{logdebug} +@item @code{logtrace} +@end itemize + +Only use @strong{ONE} of these tags. + +The default tag is @code{lognone} which disables logging completely. + +@code{logging.Logger} defines the logging interface. It is faintly inspired by the experimental @url{https://pkg.go.dev/golang.org/x/exp/slog) package, in that it differentiates explicit context logging, slog}. + + +@section Tools + +Located in the @file{dev/} directory of the source code repository. + + +@subsection Test data generation + +@example +go run ./dev/gendata/ <directory> +@end example + +Outputs bytecodes and templates for test data scenarios used in `engine` unit tests. + + +@subsection Interactive runner + +@example +go run ./dev/interactive [-d <data_directory>] [--root <root_symbol>] [--session-id <session_id>] [--persist] +@end example + +Creates a new interactive session using @code{engine.DefaultEngine}, starting execution at symbol @code{root_symbol} + +@code{data_directory} points to a directory where templates and bytecode is to be found (in the same format as generated by @file{dev/gendata}). + +If @code{data_directory} is not set, current directory will be used. + +if @code{root_symbol} is not set, the symbol @code{root} will be used. + +if @code{session_id} is set, mutable data will be stored and retrieved keyed by the given identifer (if implemented). + +If @code{persist} is set, the execution state will be persisted across sessions. + + +@subsection Assembler + +@example +go run ./dev/asm <assembly_file> +@end example + +Will output bytecode on STDOUT generated from a valid assembly file. + + +@subsection Disassembler + +@example +go run ./dev/disasm/ <binary_file> +@end example + +Will list all the instructions on STDOUT from a valid binary file. + + +@subsection Interactive case examples + +Found in @file{examples/}. + +Be sure to @code{make examples} before running them. + +Can be run with: + +@example +go run ./examples/<case> [...] +@end example + +except helloworld which is run as + +@example +go run ./dev/interactive -d ./examples/helloworld [...] +@end example + +The available options are the same as for the @file{dev/interactive} tool. + +Contents of the case directory: + +@table @file +@item *.vis +assembly code. +@item *.bin +bytecode for each node symbol (only available after make). +@item *.txt.orig +default contents of a single data entry. +@item *.txt +current contents of a single data entry (only available after make). +@end table + + +@section Assembly examples + +See @file{testdata/*.vis} + + +@section Bytecode example + +Currently the following rules apply for encoding in version @code{0}: + +@itemize +@item A code instruction is a @emph{big-endian} 2-byte value. See @file{vm/opcodes.go} for valid opcode values. +@item @code{symbol} value is encoded as @emph{one byte} of string length, after which the byte-value of the string follows. +@item @code{size} value is encoded as @emph{one byte} of numeric length, after which the @emph{big-endian} byte-value of the integer follows. +@item @code{signal} value is encoded as @emph{one byte} of byte length, after which a byte-array representing the defined signal follows. +@end itemize + + +@subsection Example + +(Minimal, WIP) + +@verbatim +000a 03666f6f 05746f666f6f # MOUT tofoo foo - display a menu entry for choice "foo", described by "to foo" +0008 03666f6f 03626172 # INCMP bar foo - move to node "bar" if input is "FOO" +0001 0461696565 01 01 # CATCH aiee 1 1 - move to node "aiee" (and immediately halt) if input match flag (1) is not set (1) +0003 04616263 020104 # LOAD abc 260 - execute code symbol "abc" with a result size limit of 260 (2 byte BE integer, 0x0104) +0003 04646566 00 # LOAD def 0 - execute code symbol "abc" with no size limit (sink) +0005 04616263 # MAP abc - make "abc" available for renderer +0007 # HALT - stop execution (require new input to continue) +0006 0461313233 # MOVE a123 - move to node "a123" (regardless of input) +0007 # HALT - stop execution +@end verbatim diff --git a/doc/texinfo/engine.texi b/doc/texinfo/engine.texi @@ -0,0 +1,64 @@ +@node engine +@chapter Using vise + +Implementers of @code{vise} should interface with the system using the @code{engine} module. + +The engine comes in two implementations, one volatile base implemetnation and a subclass that includes persistent state. + + +@section Modes of operation + +The @code{engine} module provides three different modes of operation for the engine implementations. + + +@subsection Manual operation + +Directly interaction with an @code{engine.Engine} instance. + +The engine is manually initialized, and execution must be explicitly triggered with input every time the VM yields control. + +Output flushing must also be operated manually. + +The interface is the same for both persistent and volatile operation. + + +@subsection Synchronous loop + +Receives input from a reader and writes into to a writer, and executes the underlying @code{engine.Engine} with given inputs until execution is terminated. + +The loop may be either persistent or volatile. + +This mode drives the interactive driver execution tool. + + +@subsection Asynchronous one-shot + +Compatible with e.g. a network socket or HTTP frontend. The @code{engine.RunPersisted} method restores a persisted state and runs one single input until VM yield after which the new state is persisted. + +This mode of operation can only be used with persistent state. + + +@section Configuration + +The engine configuration defines the top-level parameters for the execution environment, including maximum output size, default language, execution entry point and more. + +Please refer to @code{engine.Config} for details. + + +@section Sessions + +The @code{engine.Config.SessionId} is used to disambiguate the end-user that is interacting with the engine. + +For example, in a @abbr{USSD} context, the @code{SessionId} may be the @emph{phone number} of the end-user. + + +@anchor{execution_context} +@section Execution context + +The engine stores the @code{SessionId} aswell as the current chosen @code{lang.Language} in the execution context. This is passed through to the VM operation, and is available for client code, specifically: + +@itemize +@item When resolving symbols with @code{LOAD}. (@code{resource.EntryFunc}). +@item When resolving menu symbols (@code{resource.Resource.GetMenu}). +@item When retrieving node templates (@code{resource.Resource.GetTemplate}). +@end itemize diff --git a/doc/texinfo/index.texi b/doc/texinfo/index.texi @@ -30,4 +30,7 @@ Released 2023 under AGPL3 @include navigation.texi @include cache.texi @include render.texi +@include engine.texi +@include language.texi @include cookbook.texi +@include dev.texi diff --git a/doc/texinfo/language.texi b/doc/texinfo/language.texi @@ -0,0 +1,16 @@ +@node language +@chapter Handling languages + + +Templates, external code symbols and menu labels can be resolved differently depending on language. + +This is enabled by the @ref{execution_context, Execution context} of the engine. Through the context, the current language, if set, is always available to client code. + +Language specification is encapsulated by the @code{lang} module, using the ISO639 language identifier standard. + + +@section Defining language + +The default language can be set in @code{engine.Config.Language}. + +It may also be set as a side-effect of bytecode execution. This is done by executing @code{LOAD} with a symbol returning an @code{ISO639} language code, while setting the @code{LANG} signal flag (see @ref{builtin_flags, Built-in signal flags}. diff --git a/doc/texinfo/overview.texi b/doc/texinfo/overview.texi @@ -4,3 +4,8 @@ An attempt at defining a small VM to handle menu interaction for size-constrained clients and servers. Original motivation was to create a simple templating renderer for USSD clients, combined with an agnostic data-retrieval reference that may conceal any level of complexity. + + +@section Synopsis + +TODO diff --git a/doc/texinfo/signals.texi b/doc/texinfo/signals.texi @@ -18,7 +18,8 @@ Branching is defined using either the @code{CATCH} or @code{CROAK} instructions. The client specifies whether or not a set flag should be reset on next yield. If not, it is the responsiblity of the client to reset the flag when necessary. -@section Builtin signal flags +@anchor{builtin_flags} +@section Built-in signal flags For the numeric values of the signals, please refer to the signals appendix. diff --git a/doc/texinfo/tools.texi b/doc/texinfo/tools.texi @@ -0,0 +1,4 @@ +@node tools +@chapter Development tools + +