Symbol Table System for GEMSTEP

Posted Sunday, March 13, 2022 by Sri.Tagged PROJECT, GEMSTEP

The GEMSTEP simulator engine lets you create a blueprint creates various SM ENTITIES that can be scripted in GEMSCRIPT. The text version aka "ScriptText" presumes you know all the names of the entity types, but for a GUI we need to provide the lists of valid names and types you can use. That's where symbol data comes in.

GEMSTEP now generates lists of symbols specific to each blueprint.

Kinds of Entities

Here is the list of entities that produce symbol data for use by the user interface:

keywords,       // the list of compiler opcodes
ctors, // the list of compiler types (aka agent prop types)
props, methods, // sm_objects always have named props and methods
features, // sm_module list. an sm_module also is an sm_object
blueprints, // sm_bundle is a collection of named props, methods, and features
methodSig, // sm_method parameters and return type
arg, // argument type definition used by methodSig
context, // additional memory dictionary for this symbol
error, // script debug info
unitText // text representation of the symbol for debug purposes

Entity Symbol Data Representation

Each declared SM_ENTITY's properties can be represented using the TSymbolData type. Each entity type only uses a few of these fields. For example, the keywords symbol dictionary would only contain { keywords: string[] }.

type TSymbolData  = {
// read-only dictionaries
keywords?: string[]; // a list of valid keywords
ctors?: { [name: string]: TSymbolData }; // constructor object if needed (used by var- props)
blueprints?: { [name: string]: TSymbolData }; // blueprints
props?: { [name: string]: TSymbolData };
methods?: { [name: string]: TSymMethodSig };
features?: { [name: string]: TSymbolData };
context?: { [line: number]: any }; // line number for a root statement
methodSig?: TSymMethodSig; // arg choices
arg?: TSymArg; // arg definition string 'name:type'
// compiler status
error?: TSymbolError; // debugging if error
unitText?: string; // the scriptText word associated with symbol
// supporting types
type TSymArg = `${string}:${TSValidType}` | TSEnum;
type TMethodSig = { args?: TSymArg[]; returns?: TSymArg }
type TSymbolError = { code: TSymbolErrorCodes; info: string; };

NOTE: This data type is used both for declaring the original symbol dictionaries for the blueprint AND as a return data type for script validation (described below).

Performing User Script Validation

We also have to check every script line for validity, which requires a data structure that parses an entire script line and returns (1) the available choices available for each position given its keywod and (2) whether the user-provided data is valid, or the reason it is invalid.

Each script line is an array of [ keyword, ...args ], and each array element needs to have a corresponding validation result. The validation operation is handled by each keyword module's validate(scriptUnit:TScriptUnit) method, which returns a TValidatedScriptUnit as a result which has (1) an array of TSymbolData that uses the error property to signal a problem and (2) a text representation of the validated tokens for easier debugging.

type TValidatedScriptUnit = {
validationTokens: TSymbolData[];
validationLog?: string[];

// supporting types
type TScriptUnit = IToken[];

Use WIZCORE.ValidateLine( scriptUnitToTest ) to retrieve a TValidatedScriptUnit. The scriptUnit can be pulled from script_page[cur_linenum].

Using Validation Results to Render GUI

For data entry UI, symbols provides the valid choices available. The TValidatedScriptUnit data has the array of validatedTokens that each contain the (1) symbols and (2) errors for each token.

The WIZCORE.SymbolToViewData( symbolData ) returns a TSymbolViewData object that has the same keys as TSymbolData converted to string arrays. These arrays can be used to fill out an <select><option></select>. The keys of TSymbolViewData can be used to set <optgroup>.

type TSymbolViewData = {
keywords?: { items: string[]; info: string };
features?: { items: string[]; info: string };
props?: { items: string[]; info: string };
methods?: { items: string[]; info: string };
arg?: { items: string[]; info: string };
error?: { info: string };
unitText?: string; // the scriptText word associated with symbol