dev.html (27188B)
1 <!DOCTYPE html> 2 <html> 3 <!-- Created by GNU Texinfo 7.1, https://www.gnu.org/software/texinfo/ --> 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 6 <!-- Released 2023 under AGPL3 --> 7 <title>dev (vise)</title> 8 9 <meta name="description" content="dev (vise)"> 10 <meta name="keywords" content="dev (vise)"> 11 <meta name="resource-type" content="document"> 12 <meta name="distribution" content="global"> 13 <meta name="Generator" content="makeinfo"> 14 <meta name="viewport" content="width=device-width,initial-scale=1"> 15 16 <link href="index.html" rel="start" title="Top"> 17 <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents"> 18 <link href="index.html" rel="up" title="Top"> 19 <link href="cookbook.html" rel="next" title="cookbook"> 20 <link href="exceptions.html" rel="prev" title="exceptions"> 21 <style type="text/css"> 22 <!-- 23 a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em} 24 div.example {margin-left: 3.2em} 25 span:hover a.copiable-link {visibility: visible} 26 ul.mark-bullet {list-style-type: disc} 27 --> 28 </style> 29 30 31 </head> 32 33 <body lang="en"> 34 <div class="chapter-level-extent" id="dev"> 35 <div class="nav-panel"> 36 <p> 37 Next: <a href="cookbook.html" accesskey="n" rel="next">Common patterns</a>, Previous: <a href="exceptions.html" accesskey="p" rel="prev">Exceptional states</a>, Up: <a href="index.html" accesskey="u" rel="up">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p> 38 </div> 39 <hr> 40 <h2 class="chapter" id="Developing-with-vise"><span>11 Developing with vise<a class="copiable-link" href="#Developing-with-vise"> ¶</a></span></h2> 41 42 43 <ul class="mini-toc"> 44 <li><a href="#Code-repository-structure" accesskey="1">Code repository structure</a></li> 45 <li><a href="#Interacting-with-vise" accesskey="2">Interacting with <code class="code">vise</code></a></li> 46 <li><a href="#Resolving-resources" accesskey="3">Resolving resources</a></li> 47 <li><a href="#Data-provider" accesskey="4">Data provider</a></li> 48 <li><a href="#Logging" accesskey="5">Logging</a></li> 49 <li><a href="#Tools" accesskey="6">Tools</a></li> 50 <li><a href="#Assembly-examples" accesskey="7">Assembly examples</a></li> 51 <li><a href="#Bytecode-example" accesskey="8">Bytecode example</a></li> 52 </ul> 53 <div class="section-level-extent" id="Code-repository-structure"> 54 <h3 class="section"><span>11.1 Code repository structure<a class="copiable-link" href="#Code-repository-structure"> ¶</a></span></h3> 55 56 <dl class="table"> 57 <dt><code class="code">asm</code></dt> 58 <dd><p>Assembly parser and compiler. 59 </p></dd> 60 <dt><code class="code">cache</code></dt> 61 <dd><p>Holds and manages all loaded content. 62 </p></dd> 63 <dt><code class="code">db</code></dt> 64 <dd><p>Provides interface and implementations for data storage and retrieval backends. 65 </p></dd> 66 <dt><code class="code">engine</code></dt> 67 <dd><p>Outermost interface. Orchestrates execution of bytecode against input. 68 </p></dd> 69 <dt><code class="code">lang</code></dt> 70 <dd><p>Validation and specification of language context. 71 </p></dd> 72 <dt><code class="code">logging</code></dt> 73 <dd><p>Logging interface and build tags for loglevels. 74 </p></dd> 75 <dt><code class="code">persist</code></dt> 76 <dd><p>Provides ‘state‘ and ‘cache‘ persistence across asynchronous vm executions. 77 </p></dd> 78 <dt><code class="code">render</code></dt> 79 <dd><p>Renders menu and templates, and enforces output size constraints. 80 </p></dd> 81 <dt><code class="code">resource</code></dt> 82 <dd><p>Resolves bytecode, translations, templates and menu symbols from external symbols. 83 </p></dd> 84 <dt><code class="code">state</code></dt> 85 <dd><p>Holds the bytecode buffer, error states and navigation states. 86 </p></dd> 87 <dt><code class="code">vm</code></dt> 88 <dd><p>Defines instructions, and applies transformations according to the instructions. 89 </p></dd> 90 </dl> 91 92 93 </div> 94 <div class="section-level-extent" id="Interacting-with-vise"> 95 <h3 class="section"><span>11.2 Interacting with <code class="code">vise</code><a class="copiable-link" href="#Interacting-with-vise"> ¶</a></span></h3> 96 97 <p>Implementers of <code class="code">vise</code> should interface with the system using the <code class="code">engine</code> module. 98 </p> 99 <p>The engine comes in two implementations, one volatile base implemetnation and a subclass that includes persistent state. 100 </p> 101 102 <ul class="mini-toc"> 103 <li><a href="#Modes-of-operation" accesskey="1">Modes of operation</a></li> 104 <li><a href="#Configuration" accesskey="2">Configuration</a></li> 105 <li><a href="#Sessions" accesskey="3">Sessions</a></li> 106 <li><a href="#Execution-context" accesskey="4">Execution context</a></li> 107 <li><a href="#Blocking-execution" accesskey="5">Blocking execution</a></li> 108 </ul> 109 <div class="subsection-level-extent" id="Modes-of-operation"> 110 <h4 class="subsection"><span>11.2.1 Modes of operation<a class="copiable-link" href="#Modes-of-operation"> ¶</a></span></h4> 111 112 <p>The <code class="code">engine</code> module provides three different modes of operation for the engine implementations. 113 </p> 114 115 <ul class="mini-toc"> 116 <li><a href="#Manual-operation" accesskey="1">Manual operation</a></li> 117 <li><a href="#Synchronous-loop" accesskey="2">Synchronous loop</a></li> 118 <li><a href="#Asynchronous-one_002dshot" accesskey="3">Asynchronous one-shot</a></li> 119 </ul> 120 <div class="subsubsection-level-extent" id="Manual-operation"> 121 <h4 class="subsubsection"><span>11.2.1.1 Manual operation<a class="copiable-link" href="#Manual-operation"> ¶</a></span></h4> 122 123 <p>Directly interaction with an <code class="code">engine.Engine</code> instance. 124 </p> 125 <p>The engine is manually initialized, and execution must be explicitly triggered with input every time the VM yields control. 126 </p> 127 <p>Output flushing must also be operated manually. 128 </p> 129 <p>The interface is the same for both persistent and volatile operation. 130 </p> 131 132 </div> 133 <div class="subsubsection-level-extent" id="Synchronous-loop"> 134 <h4 class="subsubsection"><span>11.2.1.2 Synchronous loop<a class="copiable-link" href="#Synchronous-loop"> ¶</a></span></h4> 135 136 <p>Receives input from a reader and writes into to a writer, and executes the underlying <code class="code">engine.Engine</code> with given inputs until execution is terminated. 137 </p> 138 <p>The loop may be either persistent or volatile. 139 </p> 140 <p>This mode drives the interactive driver execution tool. 141 </p> 142 143 </div> 144 <div class="subsubsection-level-extent" id="Asynchronous-one_002dshot"> 145 <h4 class="subsubsection"><span>11.2.1.3 Asynchronous one-shot<a class="copiable-link" href="#Asynchronous-one_002dshot"> ¶</a></span></h4> 146 147 <p>Compatible with e.g. a network socket or HTTP frontend. The <code class="code">engine.RunPersisted</code> method restores a persisted state and runs one single input until VM yield after which the new state is persisted. 148 </p> 149 <p>This mode of operation can only be used with persistent state. 150 </p> 151 152 </div> 153 </div> 154 <div class="subsection-level-extent" id="Configuration"> 155 <h4 class="subsection"><span>11.2.2 Configuration<a class="copiable-link" href="#Configuration"> ¶</a></span></h4> 156 157 <p>The engine configuration defines the top-level parameters for the execution environment, including maximum output size, default language, execution entry point and more. 158 </p> 159 <p>Please refer to <code class="code">engine.Config</code> for details. 160 </p> 161 162 <a class="anchor" id="sessions"></a></div> 163 <div class="subsection-level-extent" id="Sessions"> 164 <h4 class="subsection"><span>11.2.3 Sessions<a class="copiable-link" href="#Sessions"> ¶</a></span></h4> 165 166 <p>The <code class="code">engine.Config.SessionId</code> is used to disambiguate the end-user that is interacting with the engine. 167 </p> 168 <p>For example, in a <abbr class="abbr">USSD</abbr> context, the <code class="code">SessionId</code> may be the <em class="emph">phone number</em> of the end-user. 169 </p> 170 171 <a class="anchor" id="execution_005fcontext"></a></div> 172 <div class="subsection-level-extent" id="Execution-context"> 173 <h4 class="subsection"><span>11.2.4 Execution context<a class="copiable-link" href="#Execution-context"> ¶</a></span></h4> 174 175 <p>The engine stores the <code class="code">SessionId</code> aswell as the current chosen <code class="code">lang.Language</code> in the execution context. This is passed through to the VM operation, and is available for client code, specifically: 176 </p> 177 <ul class="itemize mark-bullet"> 178 <li>When resolving symbols with <code class="code">LOAD</code>. (<code class="code">resource.EntryFunc</code>). 179 </li><li>When resolving menu symbols (<code class="code">resource.Resource.GetMenu</code>). 180 </li><li>When retrieving node templates (<code class="code">resource.Resource.GetTemplate</code>). 181 </li></ul> 182 183 184 </div> 185 <div class="subsection-level-extent" id="Blocking-execution"> 186 <h4 class="subsection"><span>11.2.5 Blocking execution<a class="copiable-link" href="#Blocking-execution"> ¶</a></span></h4> 187 188 <p>Using the <code class="code">engine.SetFirst()</code> method, a function may be defined that executes before the pending bytecode in the VM state. 189 </p> 190 <p>The function uses the same signature as the external functions executed by <code class="code">resource</code> for <code class="code">LOAD</code> instructions. 191 </p> 192 <p>This can be for example be used to prevent access to execution for a blocked user account, or as an override while doing maintenance. 193 </p> 194 <p>To prevent VM execution from the pre-VM check, the flag <code class="code">TERMINATE</code> should be set in the <code class="code">resource.Result.FlagSet</code> array. 195 </p> 196 197 </div> 198 </div> 199 <div class="section-level-extent" id="Resolving-resources"> 200 <h3 class="section"><span>11.3 Resolving resources<a class="copiable-link" href="#Resolving-resources"> ¶</a></span></h3> 201 202 <p>The core of implementation code is defined by implementing the <code class="code">resource.Resource</code> interface. This is also described in the <a class="ref" href="cache.html#load_005fhandler">LOAD handler</a> section. 203 </p> 204 <p>In addition to resolving external code symbols, <code class="code">resource.Resource</code> implementations also translate <em class="emph">menu labels</em> and <em class="emph">templates</em> based on the current language context, and retrieves bytecode for execution nodes. 205 </p> 206 <ul class="mini-toc"> 207 <li><a href="#Memory-resource-implementation" accesskey="1">Memory resource implementation</a></li> 208 <li><a href="#Filesystem-resource-implementation" accesskey="2">Filesystem resource implementation</a></li> 209 </ul> 210 <div class="subsection-level-extent" id="Memory-resource-implementation"> 211 <h4 class="subsection"><span>11.3.1 Memory resource implementation<a class="copiable-link" href="#Memory-resource-implementation"> ¶</a></span></h4> 212 213 <p>One of two reference implementations of <code class="code">resource.Resource</code> is the <code class="code">resource.MemResource</code> class. It enables the client to register all node and symbol resolutions at runtime, using its functions prefixed with <code class="code">Add...</code>. 214 </p> 215 <p>The <code class="code">resource.MemResource</code> implementation is primarily useful for use in tests. 216 </p> 217 218 </div> 219 <div class="subsection-level-extent" id="Filesystem-resource-implementation"> 220 <h4 class="subsection"><span>11.3.2 Filesystem resource implementation<a class="copiable-link" href="#Filesystem-resource-implementation"> ¶</a></span></h4> 221 222 <p>The Filesystem based resource implemementation is used by the <code class="code">dev/interactive</code> tool, aswell as the executable examples in <samp class="file">examples/</samp> directory. 223 </p> 224 <p>It is instantiated with a base directory location relative to which all resources are read. 225 </p> 226 227 <ul class="mini-toc"> 228 <li><a href="#Bytecode-_0028resource_002eResource_002eGetCode_0029" accesskey="1">Bytecode (<code class="code">resource.Resource.GetCode</code>)</a></li> 229 <li><a href="#Templates-_0028resource_002eResource_002eGetTemplate_0029" accesskey="2">Templates (<code class="code">resource.Resource.GetTemplate</code>)</a></li> 230 <li><a href="#Menus-_0028resource_002eResource_002eGetMenu_0029" accesskey="3">Menus (<code class="code">resource.Resource.GetMenu</code>)</a></li> 231 <li><a href="#External-symbols-_0028resource_002eResource_002eFuncFor_0029" accesskey="4">External symbols (<code class="code">resource.Resource.FuncFor</code>)</a></li> 232 </ul> 233 <div class="subsubsection-level-extent" id="Bytecode-_0028resource_002eResource_002eGetCode_0029"> 234 <h4 class="subsubsection"><span>11.3.2.1 Bytecode (<code class="code">resource.Resource.GetCode</code>)<a class="copiable-link" href="#Bytecode-_0028resource_002eResource_002eGetCode_0029"> ¶</a></span></h4> 235 236 <p>Read from <samp class="file">basedir/<node>.bin</samp>. 237 </p> 238 239 </div> 240 <div class="subsubsection-level-extent" id="Templates-_0028resource_002eResource_002eGetTemplate_0029"> 241 <h4 class="subsubsection"><span>11.3.2.2 Templates (<code class="code">resource.Resource.GetTemplate</code>)<a class="copiable-link" href="#Templates-_0028resource_002eResource_002eGetTemplate_0029"> ¶</a></span></h4> 242 243 <p>If language has been set, the template will be read from <samp class="file">basedir/<node>_<lang></samp>. For example, the <em class="emph">norwegian</em> template for the node <code class="code">root</code> will be read from <samp class="file">basedir/root_nor</samp>. 244 </p> 245 <p>If reading the language specific template fails (or if no language has been set), template will be read from <samp class="file">basedir/<node></samp>. 246 </p> 247 <p>A missing template file will result in load failure and program termination. 248 </p> 249 250 </div> 251 <div class="subsubsection-level-extent" id="Menus-_0028resource_002eResource_002eGetMenu_0029"> 252 <h4 class="subsubsection"><span>11.3.2.3 Menus (<code class="code">resource.Resource.GetMenu</code>)<a class="copiable-link" href="#Menus-_0028resource_002eResource_002eGetMenu_0029"> ¶</a></span></h4> 253 254 <p>If language has been set, the template will be read from <samp class="file">basedir/<label>_<lang>_menu</samp>. For example, the <em class="emph">norwegian</em> template for the menu label <code class="code">foo</code> will be read from <samp class="file">basedir/foo_nor_menu</samp>. 255 </p> 256 <p>If reading the language specific menu label fails (or if no language has been set), label will be read from <samp class="file">basedir/<label>_menu</samp>. 257 </p> 258 <p>If this also fails, the implementation returns the original label used for lookup. 259 </p> 260 261 </div> 262 <div class="subsubsection-level-extent" id="External-symbols-_0028resource_002eResource_002eFuncFor_0029"> 263 <h4 class="subsubsection"><span>11.3.2.4 External symbols (<code class="code">resource.Resource.FuncFor</code>)<a class="copiable-link" href="#External-symbols-_0028resource_002eResource_002eFuncFor_0029"> ¶</a></span></h4> 264 265 <p>The implementation allows setting resolver functions for symbols at runtime, using the <code class="code">resource.FsResource.AddLocalFunc</code> method. This registers an <code class="code">resource.FsResource.EntryFunc</code> with the lookup symbol as key. Note that the <code class="code">EntryFunc</code> receives the language setting through the execution context. 266 </p> 267 <p>If no function has been registered for the requested symbol, it will be looked up in the filesystem on <samp class="file">basedir/<symbol>_<lang>.txt</samp>. For example, the <em class="emph">norwegian</em> entry for the symbol <code class="code">foo</code> will be read from <samp class="file">basedir/foo_nor.txt</samp>. 268 </p> 269 <p>If reading the language specific entry fails (or if no language has been set), entry will be read from <samp class="file">basedir/<symbol>.txt</samp>. 270 </p> 271 <p>A missing entry will result in load failure and program termination. 272 </p> 273 <p>The implementation contains no built-in handling of the <code class="code">SessionId</code> supplied by the context. 274 </p> 275 276 </div> 277 </div> 278 </div> 279 <div class="section-level-extent" id="Data-provider"> 280 <h3 class="section"><span>11.4 Data provider<a class="copiable-link" href="#Data-provider"> ¶</a></span></h3> 281 282 <p>The <code class="code">db.Db</code> interface provides methods to get and set data to key-value stores. 283 </p> 284 <p>The storage keys are partitioned according to the <a class="ref" href="#sessions">session</a> context, aswell as what type of data is being stored or retrieved. 285 </p> 286 <p>The interface and the data types are defined in <code class="code">db/db.go</code>. 287 </p> 288 <p>The included implementations are: 289 </p> 290 <dl class="table"> 291 <dt><code class="code">MemDb</code></dt> 292 <dd><p>An volatile, in-process store. Used in most tests. 293 </p></dd> 294 <dt><code class="code">FsDb</code></dt> 295 <dd><p>A filesystem-backed store using subdirectories to separate sessions. 296 </p></dd> 297 <dt><code class="code">GdbmDb</code></dt> 298 <dd><p>A <a class="url" href="https://www.gnu.org/software/gdbm/gdbm">gdbm</a> backed store. 299 </p></dd> 300 <dt><code class="code">PgDb</code></dt> 301 <dd><p>A <a class="url" href="https://www.postgresql.org/">Postgres</a> backed store, using a single table with two <code class="code">BYTEA</code> columns and a connection pool. 302 </p></dd> 303 </dl> 304 305 306 <ul class="mini-toc"> 307 <li><a href="#Uses" accesskey="1">Uses</a></li> 308 <li><a href="#Using-data-provider-with-resources" accesskey="2">Using data provider with resources</a></li> 309 <li><a href="#State-persistence" accesskey="3">State persistence</a></li> 310 </ul> 311 <div class="subsection-level-extent" id="Uses"> 312 <h4 class="subsection"><span>11.4.1 Uses<a class="copiable-link" href="#Uses"> ¶</a></span></h4> 313 314 <p><code class="code">db.Db</code> may fulfill all local data requirements in <code class="code">vise</code>, including: 315 </p> 316 <ul class="itemize mark-bullet"> 317 <li>Resource retrieval 318 </li><li>State and cache persistence 319 </li><li>Application data 320 </li></ul> 321 322 323 </div> 324 <div class="subsection-level-extent" id="Using-data-provider-with-resources"> 325 <h4 class="subsection"><span>11.4.2 Using data provider with resources<a class="copiable-link" href="#Using-data-provider-with-resources"> ¶</a></span></h4> 326 327 <p>The <code class="code">resource.dbGetter</code> assists in using a <code class="code">db.Db</code> implementation. 328 </p> 329 <p>Its functions may be assigned individually to a <code class="code">resource.MenuResource</code>, allowing for co-existence of <code class="code">db.Db</code> backed resources, aswell as from other sources. 330 </p> 331 332 </div> 333 <div class="subsection-level-extent" id="State-persistence"> 334 <h4 class="subsection"><span>11.4.3 State persistence<a class="copiable-link" href="#State-persistence"> ¶</a></span></h4> 335 336 <p>Any asynchronous or consecutive synchronous operation of the <code class="code">engine.Engine</code> requires persistence of the associated <code class="code">state.State</code> and <code class="code">cache.Memory</code>. This is achieved using <code class="code">persist.Persister</code>, instantiated with a <code class="code">db.Db</code> implementation. 337 </p> 338 <p>The <code class="code">db.Db</code> used for persistence does not need to be the same as e.g. used for retrieval of resources, or even for application data. 339 </p> 340 341 </div> 342 </div> 343 <div class="section-level-extent" id="Logging"> 344 <h3 class="section"><span>11.5 Logging<a class="copiable-link" href="#Logging"> ¶</a></span></h3> 345 346 <p>Loglevels are set at compile-time using the following build tags: 347 </p> 348 <ul class="itemize mark-bullet"> 349 <li><code class="code">lognone</code> 350 </li><li><code class="code">logerror</code> 351 </li><li><code class="code">logwarn</code> 352 </li><li><code class="code">loginfo</code> 353 </li><li><code class="code">logdebug</code> 354 </li><li><code class="code">logtrace</code> 355 </li></ul> 356 357 <p>Only use <strong class="strong">ONE</strong> of these tags. 358 </p> 359 <p>The default tag is <code class="code">lognone</code> which disables logging completely. 360 </p> 361 <p><code class="code">logging.Logger</code> defines the logging interface. It is faintly inspired by the experimental <a class="url" href="https://pkg.go.dev/golang.org/x/exp/slog)%20package">slog</a>. 362 </p> 363 364 </div> 365 <div class="section-level-extent" id="Tools"> 366 <h3 class="section"><span>11.6 Tools<a class="copiable-link" href="#Tools"> ¶</a></span></h3> 367 368 <p>Located in the <samp class="file">dev/</samp> directory of the source code repository. 369 </p> 370 371 <ul class="mini-toc"> 372 <li><a href="#Test-data-generation" accesskey="1">Test data generation</a></li> 373 <li><a href="#Interactive-runner" accesskey="2">Interactive runner</a></li> 374 <li><a href="#Assembler" accesskey="3">Assembler</a></li> 375 <li><a href="#Disassembler" accesskey="4">Disassembler</a></li> 376 <li><a href="#Interactive-case-examples" accesskey="5">Interactive case examples</a></li> 377 </ul> 378 <div class="subsection-level-extent" id="Test-data-generation"> 379 <h4 class="subsection"><span>11.6.1 Test data generation<a class="copiable-link" href="#Test-data-generation"> ¶</a></span></h4> 380 381 <div class="example"> 382 <pre class="example-preformatted">go run ./dev/gendata/ <directory> 383 </pre></div> 384 385 <p>Outputs bytecodes and templates for test data scenarios used in ‘engine‘ unit tests. 386 </p> 387 388 </div> 389 <div class="subsection-level-extent" id="Interactive-runner"> 390 <h4 class="subsection"><span>11.6.2 Interactive runner<a class="copiable-link" href="#Interactive-runner"> ¶</a></span></h4> 391 392 <div class="example"> 393 <pre class="example-preformatted">go run ./dev/interactive [-d <data_directory>] [--root <root_symbol>] [--session-id <session_id>] [--persist] 394 </pre></div> 395 396 <p>Creates a new interactive session using <code class="code">engine.DefaultEngine</code>, starting execution at symbol <code class="code">root_symbol</code> 397 </p> 398 <p><code class="code">data_directory</code> points to a directory where templates and bytecode is to be found (in the same format as generated by <samp class="file">dev/gendata</samp>). 399 </p> 400 <p>If <code class="code">data_directory</code> is not set, current directory will be used. 401 </p> 402 <p>if <code class="code">root_symbol</code> is not set, the symbol <code class="code">root</code> will be used. 403 </p> 404 <p>if <code class="code">session_id</code> is set, mutable data will be stored and retrieved keyed by the given identifer (if implemented). 405 </p> 406 <p>If <code class="code">persist</code> is set, the execution state will be persisted across sessions. 407 </p> 408 409 </div> 410 <div class="subsection-level-extent" id="Assembler"> 411 <h4 class="subsection"><span>11.6.3 Assembler<a class="copiable-link" href="#Assembler"> ¶</a></span></h4> 412 413 <div class="example"> 414 <pre class="example-preformatted">go run ./dev/asm <assembly_file> 415 </pre></div> 416 417 <p>Will output bytecode on STDOUT generated from a valid assembly file. 418 </p> 419 420 </div> 421 <div class="subsection-level-extent" id="Disassembler"> 422 <h4 class="subsection"><span>11.6.4 Disassembler<a class="copiable-link" href="#Disassembler"> ¶</a></span></h4> 423 424 <div class="example"> 425 <pre class="example-preformatted">go run ./dev/disasm/ <binary_file> 426 </pre></div> 427 428 <p>Will list all the instructions on STDOUT from a valid binary file. 429 </p> 430 431 </div> 432 <div class="subsection-level-extent" id="Interactive-case-examples"> 433 <h4 class="subsection"><span>11.6.5 Interactive case examples<a class="copiable-link" href="#Interactive-case-examples"> ¶</a></span></h4> 434 435 <p>Found in <samp class="file">examples/</samp>. 436 </p> 437 <p>Be sure to <code class="code">make examples</code> before running them. 438 </p> 439 <p>Can be run with: 440 </p> 441 <div class="example"> 442 <pre class="example-preformatted">go run ./examples/<case> [...] 443 </pre></div> 444 445 <p>except helloworld which is run as 446 </p> 447 <div class="example"> 448 <pre class="example-preformatted">go run ./dev/interactive -d ./examples/helloworld [...] 449 </pre></div> 450 451 <p>The available options are the same as for the <samp class="file">dev/interactive</samp> tool. 452 </p> 453 <p>Contents of the case directory: 454 </p> 455 <dl class="table"> 456 <dt><samp class="file">*.vis</samp></dt> 457 <dd><p>assembly code. 458 </p></dd> 459 <dt><samp class="file">*.bin</samp></dt> 460 <dd><p>bytecode for each node symbol (only available after make). 461 </p></dd> 462 <dt><samp class="file">*.txt.orig</samp></dt> 463 <dd><p>default contents of a single data entry. 464 </p></dd> 465 <dt><samp class="file">*.txt</samp></dt> 466 <dd><p>current contents of a single data entry (only available after make). 467 </p></dd> 468 </dl> 469 470 471 </div> 472 </div> 473 <div class="section-level-extent" id="Assembly-examples"> 474 <h3 class="section"><span>11.7 Assembly examples<a class="copiable-link" href="#Assembly-examples"> ¶</a></span></h3> 475 476 <p>See <samp class="file">testdata/*.vis</samp> 477 </p> 478 479 </div> 480 <div class="section-level-extent" id="Bytecode-example"> 481 <h3 class="section"><span>11.8 Bytecode example<a class="copiable-link" href="#Bytecode-example"> ¶</a></span></h3> 482 483 <p>Currently the following rules apply for encoding in version <code class="code">0</code>: 484 </p> 485 <ul class="itemize mark-bullet"> 486 <li>A code instruction is a <em class="emph">big-endian</em> 2-byte value. See <samp class="file">vm/opcodes.go</samp> for valid opcode values. 487 </li><li><code class="code">symbol</code> value is encoded as <em class="emph">one byte</em> of string length, after which the byte-value of the string follows. 488 </li><li><code class="code">size</code> value is encoded as <em class="emph">one byte</em> of numeric length, after which the <em class="emph">big-endian</em> byte-value of the integer follows. 489 </li><li><code class="code">signal</code> value is encoded as <em class="emph">one byte</em> of byte length, after which a byte-array representing the defined signal follows. 490 </li></ul> 491 492 493 <ul class="mini-toc"> 494 <li><a href="#Example" accesskey="1">Example</a></li> 495 </ul> 496 <div class="subsection-level-extent" id="Example"> 497 <h4 class="subsection"><span>11.8.1 Example<a class="copiable-link" href="#Example"> ¶</a></span></h4> 498 499 <p>(Minimal, WIP) 500 </p> 501 <pre class="verbatim">000a 03666f6f 05746f666f6f # MOUT tofoo foo - display a menu entry for choice "foo", described by "to foo" 502 0008 03666f6f 03626172 # INCMP bar foo - move to node "bar" if input is "FOO" 503 0001 0461696565 01 01 # CATCH aiee 1 1 - move to node "aiee" (and immediately halt) if input match flag (1) is set (1) 504 0003 04616263 020104 # LOAD abc 260 - execute code symbol "abc" with a result size limit of 260 (2 byte BE integer, 0x0104) 505 0003 04646566 00 # LOAD def 0 - execute code symbol "abc" with no size limit (sink) 506 0005 04616263 # MAP abc - make "abc" available for renderer 507 0007 # HALT - stop execution (require new input to continue) 508 0006 0461313233 # MOVE a123 - move to node "a123" (regardless of input) 509 0007 # HALT - stop execution 510 </pre></div> 511 </div> 512 </div> 513 <hr> 514 <div class="nav-panel"> 515 <p> 516 Next: <a href="cookbook.html">Common patterns</a>, Previous: <a href="exceptions.html">Exceptional states</a>, Up: <a href="index.html">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p> 517 </div> 518 519 520 521 </body> 522 </html>