Module: Rigor::Inference::HktBodyParser

Defined in:
lib/rigor/inference/hkt_body_parser.rb

Overview

ADR-20 slice 2b — parses the body of an ‘HktRegistry::Definition` (a `String`, as populated by Slice 1’s ‘HktDirectives.parse_define` from `%arigor:v1:hkt_define` payloads) into the `HktBody` node tree the Slice 2a reducer evaluates against.

The grammar implements the full ADR-20 § D3 subset: union-of-atoms/parameterised-forms for ‘JSON.parse`’s ‘json::value` recursive sum, plus the conditional and membership forms shipped in subsequent slices. Indexed-access forms remain deferred (no concrete demand yet).

## Grammar

body         := union
union        := type_expr ("|" type_expr)*
type_expr    := atom | nominal_app | app_ref | param
              | conditional
atom         := "nil" | "true" | "false" | "bool" | "untyped"
param        := UCNAME   (when UCNAME ∈ params)
nominal_app  := class_name ("[" type_expr ("," type_expr)* "]")?
class_name   := "::"? UCNAME ("::" UCNAME)*
app_ref      := "App" "[" uri "," type_expr ("," type_expr)* "]"
uri          := IDENT ("::" IDENT)+
conditional  := "(" test "?" union ":" union ")"
test         := type_expr ("<:" | "==") type_expr
              | type_expr "in" "[" type_expr ("," type_expr)* "]"
UCNAME       := /[A-Z]\w*/
IDENT        := /[a-z_]\w*/

## Disambiguation

The same syntactic UCNAME spells both a parameter reference (‘K` when `params = [:K]`) and a nominal class name (`Integer`). The parser resolves by checking the `params` set passed to HktBodyParser.parse; an unknown UCNAME is treated as a nominal class name. `App` is reserved at the head position of an `App` form; using `App` as a class name is therefore not supported.

Atoms are kept verbatim as ‘HktBody::TypeLeaf` nodes wrapping the appropriate `Rigor::Type::*` carrier: `nil` / `true` / `false` produce `Constant` carriers; `bool` produces the `Constant<true> | Constant<false>` union; `untyped` produces `Combinator.untyped` (i.e. `Dynamic`). Nominal class names produce raw `Type::Nominal` carriers (no `name_scope` resolution at this slice — the reducer trusts the name verbatim).

Defined Under Namespace

Classes: ParseError, Parser, Token, Tokenizer

Class Method Summary collapse

Class Method Details

.parse(string, params:) ⇒ Object

Raises:

  • (ArgumentError)


61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rigor/inference/hkt_body_parser.rb', line 61

def parse(string, params:)
  raise ArgumentError, "string must be a String, got #{string.class}" unless string.is_a?(String)
  raise ArgumentError, "params must be an Array, got #{params.class}" unless params.is_a?(Array)

  params_set = params.to_h { |p| [p.to_sym, true] }
  tokens = Tokenizer.new(string).tokenize
  parser = Parser.new(tokens, params_set)
  result = parser.parse_union
  parser.expect_eof!
  result
end