The following is the official YASS formal specification (actually it's Backus–Naur Form) for the latest version of YASS. The ε represents a termination case.
ε symbolises syntactic termination (i.e. the end of a rule)
ZPE/YASS formal specification ZPE 1.14.12 (December 2026) The following productions describe the current YASS language. They replace or extend the corresponding productions in earlier formal specifications. 1. Lexical tokens and modifiers ------------------------------- ⟨scope_resolution_operator⟩ :: ⟨object_access_operator⟩ -> ⟨inheritance_keyword⟩ inherits extends ⟨scope⟩ public private protected friendly ⟨static_modifier⟩ static ⟨method_modifiers⟩ ⟨scope⟩ ⟨static_modifier⟩ | ⟨scope⟩ || | ⟨static_modifier⟩ | ε ⟨keyword⟩ assert break case catch class component count | default | do | each | else | elseif | end | enum | enumerator || | extends | finally | for | from | function | global | goto | if | implements | import | include | includes | inherits | in | is | is_set | label | let | match | module | namespace | new | not | public | private | protected | record | return | static | structure | super | switch | test | to | try | type | typeof | unset | until | var | when | while | async | await | continue The spelling include is preferred. includes remains accepted for compatibility. 2. Program and body forms -------------------------- ⟨program⟩ ⟨construct_body⟩ ⟨construct_body⟩ ⟨body⟩ ⟨construct_body⟩ ε ⟨body⟩ ⟨assert⟩ ⟨import⟩ ⟨include⟩ ⟨assign⟩ ⟨declaration⟩ | ⟨function⟩ | ⟨component⟩ | ⟨if⟩ | ⟨for⟩ | ⟨for_to⟩ || | ⟨for_each⟩ | ⟨until⟩ | ⟨while⟩ | ⟨do_while⟩ | ⟨when⟩ | ⟨match_statement⟩ | ⟨lambda_call⟩ | ⟨function_call⟩ | ⟨object_accessor⟩ | ⟨scope_resolution⟩ | ⟨increment⟩ | ⟨decrement⟩ | ⟨module⟩ | ⟨structure⟩ | ⟨enum⟩ | ⟨record⟩ | ⟨return⟩ | ⟨break⟩ | ⟨label⟩ | ⟨goto⟩ | ⟨breakpoint⟩ | ⟨scope_block⟩ | ⟨unset⟩ ⟨term⟩ ⟨identifier⟩ ⟨variable⟩ ⟨increment⟩ ⟨decrement⟩ | ⟨value⟩ | ⟨lambda_call⟩ | ⟨function_call⟩ || | ⟨object_accessor⟩ | ⟨scope_resolution⟩ | ⟨power⟩ | ⟨match_expression⟩ | ⟨matcher_expression⟩ | ⟨conditional_expression⟩ | ⟨count⟩ | ⟨cast⟩ | ⟨arrow_function⟩ | ( ⟨expression⟩ ) 3. Functions, methods, and annotations --------------------------------------- ⟨function⟩ ⟨annotations⟩ function ⟨identifier⟩ ( ⟨formal_parameters⟩ ) ⟨function_type⟩ ⟨construct_body⟩ || end function | ⟨annotations⟩ function ⟨identifier⟩ ( ⟨formal_parameters⟩ ) ⟨function_type⟩ { ⟨construct_body⟩ } ⟨method⟩ ⟨annotations⟩ ⟨method_modifiers⟩ function ⟨identifier⟩ ( ⟨formal_parameters⟩ ) ⟨function_type⟩ ⟨construct_body⟩ || end function | ⟨annotations⟩ ⟨method_modifiers⟩ function ⟨identifier⟩ ( ⟨formal_parameters⟩ ) ⟨function_type⟩ { ⟨construct_body⟩ } ⟨annotations⟩ ⟨annotation⟩ ⟨annotations⟩ ε ⟨annotation⟩ @doc ⟨annotation_value⟩ || | @date ⟨annotation_value⟩ | @directive ⟨annotation_value⟩ | @compile ⟨compile_value⟩ | @requires return | @requires permission ⟨integer⟩ | @router ⟨annotation_value⟩ | @request ⟨annotation_value⟩ | @get ⟨annotation_value⟩ | @post ⟨annotation_value⟩ | @put ⟨annotation_value⟩ | @patch ⟨annotation_value⟩ | @delete ⟨annotation_value⟩ | @head ⟨annotation_value⟩ | @options ⟨annotation_value⟩ | @any ⟨annotation_value⟩ @requires return requires the function to leave with a non-null return value. The requirement is checked when execution leaves the function, including an explicit return and normal fall-through. The compiler rejects functions that can be proven not to return a value. @requires permission N requires the active ZPE permission level to be at least N before the function body begins. User-defined functions default to level 0. Asynchronous functions were introduced in ZPE 1.14.12: ⟨async_function⟩ async function ⟨identifier⟩ ( ⟨formal_parameters⟩ ) ⟨function_type⟩ ⟨construct_body⟩ || end function | async function ⟨identifier⟩ ( ⟨formal_parameters⟩ ) ⟨function_type⟩ { ⟨construct_body⟩ } ⟨await_expression⟩ await ⟨term⟩ An async function invocation starts execution on the ZPE asynchronous executor || and returns a Future object immediately. It does not block the calling function. The await expression blocks the calling function until that Future completes and then evaluates to the async function's returned value. If the async function fails, await raises the corresponding runtime error in the calling function. Future objects expose these native methods: await() waits for completion and returns the result done() returns true when execution has completed, otherwise false on_complete(f) registers f as an asynchronous completion callback and returns the Future object; f receives the completed result Calling an async function without await is valid for fire-and-forget work. A Future is not constructed directly by YASS; it is created only by an async function invocation. The scheduled callback functions run_in and run_at use the same asynchronous executor and Future-compatible execution model. They accept a callable and schedule its invocation without executing it on the timer thread. 4. Parameters, return types, and declarations ---------------------------------------------- ⟨formal_parameters⟩ ⟨formal_parameter⟩ , ⟨formal_parameters⟩ | ⟨formal_parameter⟩ | ε || ⟨formal_parameter⟩ ⟨variable⟩ | ⟨type_expression⟩ ⟨variable⟩ || | ⟨type_expression⟩ ⟨variable⟩ = ⟨expression⟩ ⟨function_type⟩ : ⟨type_expression⟩ ε ⟨declaration⟩ var ⟨variable_declaration⟩ | let ⟨variable_declaration⟩ || | type ⟨identifier⟩ = ⟨type_expression⟩ ⟨type_expression⟩ string number boolean object record list | map | fn | mixed | ⟨identifier⟩ || | list < ⟨type_expression⟩ > | map < ⟨type_expression⟩ , ⟨type_expression⟩ > | ⟨type_expression⟩ [ ⟨integer⟩ ] Type aliases are compile-time names for type expressions, for example: type UserID = number type Scores = list<number> Typed collections and fixed-size arrays are checked when values are assigned, passed as arguments, or returned from functions. Multidimensional arrays are formed by repeating the indexed type suffix. 5. Instance and inherited-member access ---------------------------------------- ⟨object_root⟩ ⟨variable⟩ this super ⟨object_member⟩ ⟨variable⟩ ⟨identifier⟩ ⟨function_call⟩ | ⟨lambda_call⟩ || ⟨object_accessor⟩ ⟨object_root⟩ ⟨object_access_operator⟩ ⟨object_member⟩ | ⟨object_accessor⟩ ⟨object_access_operator⟩ ⟨object_member⟩ || Nested access is permitted, including UI->Button->set_text(). The variable form permits a variable to supply the member name, for example $object->$name. super is valid inside an instance method and begins method lookup at the parent of the current structure while retaining the current child instance. 6. Static, module, enum, and object-member access ------------------------------------------------- ⟨scope_resolution_root⟩ ⟨identifier⟩ ⟨scope_resolution_member⟩ ⟨identifier⟩ ⟨variable⟩ ⟨function_call⟩ ⟨scope_resolution⟩ ⟨scope_resolution_root⟩ :: ⟨scope_resolution_member⟩ || Examples: Math::random_number() Person::get_people_list() Status::OK Static methods and properties belong to their declaring structure and do not construct an instance. Private static members cannot be called externally. 7. Structures, inheritance, interfaces, and enums -------------------------------------------------- ⟨structure_id⟩ structure struct class ⟨inherits⟩ inherits ⟨identifier⟩ extends ⟨identifier⟩ ε ⟨implements⟩ implements ⟨identifier⟩ , ⟨implements⟩ | implements ⟨identifier⟩ | ε || ⟨structure⟩ ⟨structure_id⟩ ⟨identifier⟩ ⟨inherits⟩ ⟨implements⟩ ⟨namespace⟩ ⟨structure_inner⟩ end structure || | ⟨structure_id⟩ ⟨identifier⟩ ⟨inherits⟩ ⟨implements⟩ { ⟨namespace⟩ ⟨structure_inner⟩ } ⟨structure_inner⟩ ⟨structure_member⟩ ⟨structure_inner⟩ ε ⟨structure_member⟩ ⟨variable⟩ ⟨assign⟩ ⟨method⟩ ⟨interface⟩ interface ⟨identifier⟩ ⟨interface_inner⟩ end interface | interface ⟨identifier⟩ { ⟨interface_inner⟩ } || ⟨interface_inner⟩ ⟨interface_method⟩ ⟨interface_method⟩ ⟨interface_inner⟩ ⟨interface_method⟩ public function ⟨identifier⟩ ( ⟨formal_parameters⟩ ) ⟨function_type⟩ || Interfaces may contain default method bodies where supported. A structure that declares implements must satisfy every interface method contract. ⟨enum⟩ enum ⟨identifier⟩ ⟨enum_member⟩* end enum | enumerator ⟨identifier⟩ ⟨enum_member⟩* end enumerator || ⟨enum_member⟩ ⟨identifier⟩ = ⟨expression⟩ Enum members are accessed with the scope-resolution operator and must have an || assigned value. 8. Conditional, matcher, arrow, and selection expressions ---------------------------------------------------------- ⟨conditional_expression⟩ ⟨term⟩ if ⟨condition⟩ else ⟨term⟩ Only the selected branch is evaluated. The established ? ternary syntax remains || valid. ⟨arrow_function⟩ ( ⟨formal_parameters⟩ ) => ⟨expression⟩ | ⟨variable⟩ => ⟨expression⟩ || ⟨matcher_expression⟩ matcher ( ⟨matcher_entries⟩ ⟨matcher_default⟩ ) ⟨matcher_entry⟩ ⟨literal⟩ => ⟨expression⟩ ; ⟨matcher_default⟩ else => ⟨expression⟩ ; ε Matcher keys are literals, duplicate keys are compile-time errors, and only the || selected result expression is evaluated. A matcher without a matching key or else entry returns null. Match expressions evaluate their comparator once and test candidates in source order. When-is and switch-case retain first-branch-wins behaviour. 9. Template strings ------------------- ⟨template_string⟩ ` ⟨template_content⟩ ` ⟨template_content⟩ ⟨literal_text⟩ ⟨template_content⟩ | {{ ⟨expression⟩ }} ⟨template_content⟩ || | ε Template interpolation uses double braces. A normal variable is written as {{$name}}, while an expression may be written as {{function_call()}}. Templates are compiled into reusable expression fragments and only interpolated expressions are evaluated at runtime. 10. Components ------------- ⟨component⟩ component ⟨identifier⟩ ⟨component_content⟩ end component | component ⟨identifier⟩ { ⟨component_content⟩ } || ⟨component_content⟩ ⟨component_text⟩ ⟨component_content⟩ | {{ ⟨expression⟩ }} ⟨component_content⟩ || | ε Components are named, compiled renderable values. Their content is not parsed as ordinary YASS statements. A component may be called using its identifier and an object or map of interpolation values: component page <h1>Hello, {{$name}}</h1> end component print(page({"name" : "Jamie"})) Components use the same {{...}} interpolation form as template strings. A component call returns its rendered text. Components are registered in the compiled-program index and may be removed with: unset(page) After removal, the component identifier is no longer callable. Components are not ordinary functions and do not use a function body or function return type. 11. Indentation-based blocks ---------------------------- ⟨indented_header⟩ if ⟨condition⟩ : | else if ⟨condition⟩ : || | elseif ⟨condition⟩ : | else : | for ⟨for_header⟩ : | while ⟨condition⟩ : | function ⟨function_header⟩ : | class ⟨identifier⟩ ⟨inherits⟩ : | structure ⟨identifier⟩ ⟨inherits⟩ : | module ⟨identifier⟩ : | switch ⟨switch_header⟩ : | try : | catch ⟨catch_header⟩ : | finally : ⟨indented_block⟩ ⟨indented_header⟩ NEWLINE INDENT ⟨construct_body⟩ DEDENT || Tabs count as four spaces. Explicit end clauses remain accepted. 12. Assignment, mutation, and removal -------------------------------------- ⟨assignment⟩ ⟨variable⟩ = ⟨expression⟩ | ⟨variable⟩ , ⟨variable_list⟩ = ⟨expression⟩ || | ⟨accessor⟩ ⟨assignment_operator⟩ ⟨expression⟩ ⟨assignment_operator⟩ = += -= *= /= %= **= Multiple assignment permits forms such as $x, $y = get_values(). For lists and || arrays, += appends the assigned value to the collection. ⟨unset⟩ unset ( ⟨identifier_or_accessor⟩ ) ⟨is_set⟩ is_set ( ⟨identifier_or_accessor⟩ ) unset removes a variable, member, or registered component identified by its || argument. is_set tests whether the identifier or accessor is currently bound. 13. Web request and response extensions ---------------------------------------- Web functions may be annotated with routing annotations such as @router, @get, @post, @put, @patch, @delete, @head, @options, and @any. Request objects Response objects support text bodies, binary bodies, downloadable responses, additional core expression productions. 14. Semantic and compatibility constraints ------------------------------------------- 1. A static call does not construct an object; this and instance properties are 2. super is valid only inside an instance method with an inherited implementation. 3. super->method() starts lookup at the parent of the current structure. 4. The inherited implementation still operates on the current child instance. 5. Private parent methods cannot be invoked through super. 6. Interface compliance is checked at compile time and safeguarded at runtime for dynamically loaded compiled programs. 7. Only selected conditional, matcher, match, and component expressions are evaluated; unused branches are lazy. 8. Explicit end clauses remain compatible with indentation-based syntax. 9. Object access and scope resolution may be nested to arbitrary supported depth. 10. Older compiled programs using the .yex extension remain loadable; current compiled programs use .zex. Availability ------------ Inheritance, structures, modules, templates, records, and object access existed before 1.14.9. Their grammar and runtime behaviour were expanded in later releases. ZPE 1.14.9 enabled interfaces and enums by default and introduced or formalised ZEQL, database access, project compilation and resources, web routing/YWP, inheritance improvements, super, static structure methods, match/matcher expressions, indentation syntax, and typed arrays. ZPE 1.14.10 added typed collections, type aliases, default interface methods, native UI, project manifests, resource bundling, ZenLang, Graphics, NativeUIKit, and expanded native runtime support. ZPE 1.14.11 changed template and component interpolation to {{...}}, added components and component removal, added @requires return and @requires permission N, and expanded web request and response support.

There are no comments on this page.
Comments are welcome and encouraged, including disagreement and critique. However, this is not a space for abuse. Disagreement is welcome; personal attacks, harassment, or hate will be removed instantly. This site reflects personal opinions, not universal truths. If you can’t distinguish between the two, this probably isn’t the place for you. The system temporarily stores IP addresses and browser user agents for the purposes of spam prevention, moderation, and safeguarding. This data is automatically removed after fourteen days. Your email address is stored so that replies can be sent to your email address.
Comments powered by BalfComment