What the engine honors today
language_template.json is the contract for generated JSON. The interpreter does not implement every field yet. You still emit the full template. Disabled or unused fields stay in the file.
This document is the honest map so you do not promise Python-complete classes when the user will only get the subset below.
Used for lexing and parsing
| Area | Fields the reader uses |
|---|---|
| Identity | name (required, not the placeholder), extensions, language_detection.extensions |
| Source | case_sensitive, indentation_significant (stored; indent lexing is limited) |
| Identifiers | identifiers.pattern is stored; matching is currently letter/_ start, alphanumeric/_ continue |
| Comments | comments.line.enabled + markers; comments.block.enabled + pairs |
| Keywords | All keyword lists are collected so those words tokenize as keywords |
| Types | keywords.types and every builtin_types.* array (names tokenize as types) |
| Variables | variables.enabled, declaration_keywords, declaration_patterns, declaration_required, assignment_operators |
| Functions | functions.enabled, declaration_keywords, declaration_patterns, header_style, parameter_patterns, return_type_patterns, return_keywords, parameter delimiters via delimiters / tokens |
| Classes | classes.enabled, classes.declaration_keywords, classes.inheritance, classes.methods |
| Imports | imports.enabled, imports.import_keywords, imports.module_separator, imports.relative_import_token, imports.bind_as (or scope.module_scope when bind_as is omitted), imports.search_directories, imports.plugin_entry (default rescripted_register) |
| Stdlib | standard_library.automatically_imported names are imported at the start of run |
| Control flow | if / else_if / else, while, for, break, continue keyword lists |
| Literals | null.values, boolean.true_values / false_values, integer/float enabled, string.enabled, string.forms or ", escape_character |
| Tokens | statement_terminators, statement_terminator_required, argument_separator, member_separator |
| Delimiters | parentheses, brackets, blocks.delimiter open/close |
| Operators | all operators.* arrays plus operator_precedence.levels (explicit levels overwrite). operators.assignment is merged with variables.assignment_operators |
| Entry | entry_point.top_level_execution is recorded; run() still executes top-level statements |
| Builtins | builtins.functions names (host must bind implementations) |
| Custom | custom.function_kinds, custom.types, custom.decorators, custom.host_functions |
Implemented script features
- Line and block comments
- Numbers, strings, true/false/null words
let-style declarations (whatever keywords you configured)- C-style typed declarations
Type name [= expr]whenvariables.declaration_patternsorfunctions.header_style/declaration_patternsrequest type-first form - Bare assignment
name = expr(creates the name if it does not exist). Usevariables.declaration_required: falsefor languages that omitlet fn-style and extracustom.function_kindsdeclarations- C-style type-first functions
ReturnType Name(params) { body }whenfunctions.header_styleis"c_type_first"and/orfunctions.declaration_patterns/return_type_patternsdescribe that form - C-style typed parameters
Type namein any function parameter list (functions.parameter_patterns). Untypedfn add(a, b)still works voidas a return type (frombuiltin_types.void, default"void") means the call yields no valueentity Name { field = value; }stylecustom.types(fields only)- Classes / actors:
classes.declaration_keywords(for exampleactororclass), optional: Basewhenclasses.inheritanceis true, typed fields and type-first methods whenclasses.methodsis true. One instance is created per class declaration in a loaded script.engine.call("OnSpawn")dispatches to that instance’s method of the same name; the host does not pass the class name. Unqualified names in methods resolve to parameters, then instance fields/methods, then globals/host. Unknown bases (hostbind_typenot yet bound) still parse importwhenimports.enabled: keyword is whatever you listed (import,#import,#banana). The module spec is one identifier,a.b.cusingmodule_separator, or a string path. Resolution order: hostadd_library/add_library_file(exact name, then last segment), then a script file (a.b.c→a/b/c+ language extension) beside the importer, in., thenimports.search_directories, thenadd_search_path. A leadingrelative_import_tokensearches only the importer’s directory. Imported scripts run in their own environment (host binds still visible).bind_as"namespace"binds the last segment as a map (math.sqrt);"globals"copies exported names into the importer;"both"does both. Omitbind_asandscope.module_scopetrue means namespace, otherwise flatten. CMake does not register libraries; the host callsadd_library. Host may alsoadd_library(name, header_or_cpp)(best-effortextern "C"prototypes already linked) orload_plugina.dll/.dylib/.sowhoseimports.plugin_entry/rescripted_register(Engine&)typicallyadd_librarys itself. Scripts cannot import raw C++ off disk. Not a C#includemerge. Top-level of a script module runs once.- Prefix decorators (
@nameor yourprefix) - Assignment, compound assignment
+= -= *= /=when those tokens are inoperators.assignment/variables.assignment_operators, arithmetic, comparison, equality,&&||andor, unary-!not - Calls, indexing
[i], member.nameon maps - Array literals
[a, b] if/else/ else-if: parentheses around the condition are optional; braces around the body are optional (a single statement is a block).else { if ... }covers else-if when the language has noelse ifkeywordwhile,forover arrays orfor x Nnumeric rangereturn,break,continue- Optional statement terminators when
tokens.statement_terminator_requiredis false +concatenates if either side is a string (to_stringon the other)- Host calls and script-defined functions (recursion works)
- Load registers functions;
runexecutes top-level (including class instances and imports);unloaddrops that script’s functions and vars
Present in the JSON, not fully executed yet
Keep these fields. Do not delete them. Do not tell the user they already have a complete implementation of:
- Indentation-as-syntax (Python-style blocks) as a first-class lexer
- Structs, unions, enums, interfaces, traits (use
classesfor class/actor types with methods) from/ alias / wildcard import forms; nested package objects forimport a.b.cbindinga(the last segment is bound instead)- Generics, pointers, references
- Pattern matching, exceptions, async, concurrency
- Preprocessor / macros
- Full grammar.rules interpreter (the engine uses its own parser, not EBNF execution)
- Tooling commands (formatter, LSP, etc.)
- Compile-to-native of user scripts
If the user needs one of those as syntax sugar, try custom.* plus host functions first.
functions.header_style
Optional. "" (default) means declarations use declaration_keywords (fn, command, …). "c_type_first" means ReturnType Name(params) headers are parsed even when declaration_keywords is empty. Keyword-style fn still works if those keywords are listed. The same type-first behavior is enabled when declaration_patterns contains "c_type_first" or a pattern like "Type Name(params)".
Defaults the engine adds
If operator lists are sparse, the reader still installs + - * / % == != < <= > >= && || and or and unary ! so expressions work. Your precedence table, if present, wins for listed operators. : is tokenized when classes.inheritance is true.