Module: Jade::AST

Extended by:
AST, Nodes
Included in:
AST
Defined in:
lib/jade/ast.rb,
lib/jade/ast/node.rb,
lib/jade/ast/nodes.rb,
lib/jade/ast/pretty_printer.rb

Defined Under Namespace

Modules: Node, Nodes, Pattern, PrettyPrinter

Instance Method Summary collapse

Methods included from Nodes

define

Instance Method Details

#assignObject



119
120
121
122
123
124
125
126
127
# File 'lib/jade/ast.rb', line 119

def assign
  ->((pattern_node, _assignment, expression_node)) do
    Assign[
      pattern_node,
      expression_node,
      pattern_node.range.begin...expression_node.range.end,
    ]
  end
end

#bindObject



129
130
131
132
133
134
135
136
137
# File 'lib/jade/ast.rb', line 129

def bind
  ->((pattern_node, _bind, expression_node)) do
    Bind[
      pattern_node,
      expression_node,
      pattern_node.range.begin...expression_node.range.end,
    ]
  end
end

#binding_patternObject



435
436
437
438
439
# File 'lib/jade/ast.rb', line 435

def binding_pattern
  ->(identifier) do
    Pattern::Binding[identifier.value, identifier.range]
  end
end

#bodyObject



158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/jade/ast.rb', line 158

def body
  ->(expressions) do
    if expressions.empty?
      Body[[], nil]

    else
      Body[
        expressions,
        expressions.first.range.begin...expressions.last.range.end,
      ]
    end
  end
end

#case_else_branchObject



409
410
411
412
413
414
415
416
417
# File 'lib/jade/ast.rb', line 409

def case_else_branch
  ->((else_token, body)) do
    CaseOfBranch[
      Pattern::Wildcard.new(range: else_token.range),
      body,
      else_token.range.begin...body.range.end,
    ]
  end
end

#case_ofObject



389
390
391
392
393
394
395
396
397
# File 'lib/jade/ast.rb', line 389

def case_of
  ->((case_token, expression, branches, else_branch, end_token)) do
    CaseOf[
      expression,
      else_branch ? [*branches, else_branch] : branches,
      case_token.range.begin...end_token.range.end,
    ]
  end
end

#case_of_branchObject



399
400
401
402
403
404
405
406
407
# File 'lib/jade/ast.rb', line 399

def case_of_branch
  ->((in_token, pattern, body)) do
    CaseOfBranch[
      pattern,
      body,
      in_token.range.begin...body.range.end,
    ]
  end
end

#char_literalObject



102
103
104
# File 'lib/jade/ast.rb', line 102

def char_literal
  ->(token) { CharLiteral[token.value, token.range] }
end

#constructor_patternObject



441
442
443
444
445
446
447
448
449
450
# File 'lib/jade/ast.rb', line 441

def constructor_pattern
  ->((constructor, patterns_list)) do
    Pattern::Constructor.new(
      constructor:,
      patterns: patterns_list.items,
      trailing_comma: patterns_list.trailing_comma,
      range: constructor.range.begin...(patterns_list.items.last&.range&.end || constructor.range.end),
    )
  end
end

#constructor_referenceObject



149
150
151
152
153
154
155
156
# File 'lib/jade/ast.rb', line 149

def constructor_reference
  ->(constant) do
    ConstructorReference[
      constant.value,
      constant.range,
    ]
  end
end

#expose_allObject



539
540
541
542
543
# File 'lib/jade/ast.rb', line 539

def expose_all
  ->(dot_dot) do
    ExposeAll[dot_dot.range]
  end
end

#expose_asObject



573
574
575
576
577
# File 'lib/jade/ast.rb', line 573

def expose_as
  ->((constant)) do
    ExposeAs[constant.value, constant.range]
  end
end

#expose_listObject



545
546
547
548
549
550
551
552
553
# File 'lib/jade/ast.rb', line 545

def expose_list
  ->(comma_list) do
    ExposeList.new(
      items: comma_list.items,
      trailing_comma: comma_list.trailing_comma,
      range: comma_list.items.first.range.begin...comma_list.items.last.range.end,
    )
  end
end

#expose_noneObject



533
534
535
536
537
# File 'lib/jade/ast.rb', line 533

def expose_none
  ->(_) do
    ExposeNone[nil]
  end
end

#expose_typeObject



561
562
563
564
565
# File 'lib/jade/ast.rb', line 561

def expose_type
  ->((constant)) do
    ExposeType[constant.value, constant.range]
  end
end

#expose_type_expandObject



567
568
569
570
571
# File 'lib/jade/ast.rb', line 567

def expose_type_expand
  ->((constant)) do
    ExposeTypeExpand[constant.value, constant.range]
  end
end

#expose_valueObject



555
556
557
558
559
# File 'lib/jade/ast.rb', line 555

def expose_value
  ->((identifier)) do
    ExposeValue[identifier.value, identifier.range]
  end
end

#function_callObject



262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/jade/ast.rb', line 262

def function_call
  ->(callee, _lparen, args_list, rparen) do
    FunctionCall.new(
      callee:,
      args: args_list.items,
      infix: false,
      dictionaries: [],
      trailing_comma: args_list.trailing_comma,
      range: callee.range.begin...rparen.range.end,
    )
  end
end

#function_declarationObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/jade/ast.rb', line 172

def function_declaration
  ->(tokens) do
    tokens => [def_token, name, params_list, return_type, body, end_token]

    FunctionDeclaration.new(
      name: name.value,
      params: params_list.items,
      return_type:,
      body:,
      trailing_comma: params_list.trailing_comma,
      range: def_token.range.begin...end_token.range.end,
    )
  end
end

#function_declaration_paramObject



187
188
189
190
191
192
193
194
195
196
197
# File 'lib/jade/ast.rb', line 187

def function_declaration_param
  ->(tokens) do
    tokens => [name, type]

    FunctionDeclarationParam[
      name.value,
      type,
      name.range.begin...type.range.end,
    ]
  end
end

#groupingObject



493
494
495
496
497
498
499
500
# File 'lib/jade/ast.rb', line 493

def grouping
  ->((lparen_token, expression, rparen_token)) do
    Grouping[
      expression,
      lparen_token.range.begin...rparen_token.range.end
    ]
  end
end

#if_then_elseObject



362
363
364
365
366
367
368
369
370
371
# File 'lib/jade/ast.rb', line 362

def if_then_else
  ->((if_token, condition, if_branch, else_branch, end_token)) do
    IfThenElse[
      condition,
      if_branch,
      else_branch,
      if_token.range.begin...end_token.range.end,
    ]
  end
end

#implementationObject



669
670
671
672
673
674
675
676
677
678
679
# File 'lib/jade/ast.rb', line 669

def implementation
  ->((implements_token, interface, applied_type, extends, functions, end_token)) do
    Implementation[
      interface.value,
      applied_type,
      extends.map(&:value),
      functions,
      implements_token.range.begin...end_token.range.end,
    ]
  end
end

#implementation_functionObject



681
682
683
684
685
686
687
688
689
690
691
692
693
694
# File 'lib/jade/ast.rb', line 681

def implementation_function
  ->((name, fn)) do
    canonical_name = case name.type
                     in :identifier then name.value
                     else "(#{name.value})"
                     end

    ImplementationFunction[
      canonical_name,
      fn,
      name.range.begin...fn.range.end,
    ]
  end
end

#import_declarationObject



340
341
342
343
344
345
346
347
348
349
# File 'lib/jade/ast.rb', line 340

def import_declaration
  ->((import, module_parts, as, exposing)) do
    ImportDeclaration[
      module_parts.map(&:value).join('.'),
      as,
      exposing,
      import.range.begin...(module_parts.last.range.end),
    ]
  end
end

#infix_applicationObject



251
252
253
254
255
256
257
258
259
260
# File 'lib/jade/ast.rb', line 251

def infix_application
  ->(left, token_op, right) do
    InfixApplication[
      left,
      InfixOperator[token_op.value, token_op.range],
      right,
      left.range.begin...right.range.end,
    ]
  end
end

#interface_declarationObject



696
697
698
699
700
701
702
703
704
705
# File 'lib/jade/ast.rb', line 696

def interface_declaration
  ->((interface_token, name, type_param, functions, end_token)) do
    InterfaceDeclaration[
      name.value,
      type_param,
      functions,
      interface_token.range.begin...end_token.range.end,
    ]
  end
end

#interface_function_declObject



707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
# File 'lib/jade/ast.rb', line 707

def interface_function_decl
  ->((name, type)) do
    canonical_name =
      case name.type
      in :identifier then name.value
      else "(#{name.value})"
      end

    InterfaceFunctionDecl[
      canonical_name,
      type,
      name.range.begin...type.range.end,
    ]
  end
end

#interop_functionObject



647
648
649
650
651
652
653
654
655
# File 'lib/jade/ast.rb', line 647

def interop_function
  ->((name, type_expression)) do
    InteropFunction[
      name.value,
      type_expression,
      name.range.begin...type_expression.range.end,
    ]
  end
end

#interop_import_declarationObject



628
629
630
631
632
633
634
635
636
# File 'lib/jade/ast.rb', line 628

def interop_import_declaration
  ->((uses_token, interop_module, _with_token, interop_functions, end_token)) do
    InteropImportDeclaration[
      interop_module,
      interop_functions,
      uses_token.range.begin...end_token.range.end,
    ]
  end
end

#interop_moduleObject



638
639
640
641
642
643
644
645
# File 'lib/jade/ast.rb', line 638

def interop_module
  ->(parts) do
    InteropModule[
      parts.map(&:value).join('::'),
      parts.first.range.begin...parts.last.range.end,
    ]
  end
end

#keyed_callObject



321
322
323
324
325
326
327
328
329
330
# File 'lib/jade/ast.rb', line 321

def keyed_call
  ->(callee, lparen, fields_list, rparen) do
    KeyedCall.new(
      callee:,
      fields: fields_list.items,
      trailing_comma: fields_list.trailing_comma,
      range: lparen.range.begin...rparen.range.end,
    )
  end
end

#keyed_patternObject



332
333
334
335
336
337
338
# File 'lib/jade/ast.rb', line 332

def keyed_pattern
  ->(fields) do
    fields_list = Parsing::Combinators::CommaList.new(items: fields, trailing_comma: false)
    record_pattern.call([fields.first, fields_list, fields.last])
      .then { Parsing::Combinators::CommaList.new(items: [it], trailing_comma: false) }
  end
end

#keyed_variantObject



314
315
316
317
318
319
# File 'lib/jade/ast.rb', line 314

def keyed_variant
  ->((lparen, fields, rparen)) do
    type_record.call([lparen, nil, fields, rparen])
      .then { Parsing::Combinators::CommaList.new(items: [it], trailing_comma: false) }
  end
end

#lambdaObject



522
523
524
525
526
527
528
529
530
531
# File 'lib/jade/ast.rb', line 522

def lambda
  ->((lead_token, params_list, body, rbrace_token)) do
    Lambda.new(
      params: params_list.items,
      body:,
      trailing_comma: params_list.trailing_comma,
      range: lead_token.range.begin...rbrace_token.range.end,
    )
  end
end

#listObject



579
580
581
582
583
584
585
586
587
# File 'lib/jade/ast.rb', line 579

def list
  ->((lbrack, items_list, rbrack)) do
    List.new(
      items: items_list.items,
      trailing_comma: items_list.trailing_comma,
      range: lbrack.range.begin...rbrack.range.end,
    )
  end
end

#list_patternObject



482
483
484
485
486
487
488
489
490
491
# File 'lib/jade/ast.rb', line 482

def list_pattern
  ->((lbrack, (patterns_list, tail), rbrack)) do
    Pattern::List.new(
      patterns: patterns_list.items,
      rest: tail,
      trailing_comma: patterns_list.trailing_comma,
      range: lbrack.range.begin...rbrack.range.end,
    )
  end
end

#literalObject



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/jade/ast.rb', line 106

def literal
  ->(token) do
    value =
      case token.type
      in :int   then token.value.to_i
      in :float then token.value.to_f
      in :bool  then token.value == 'True'
      end

    Literal[value, token.range]
  end
end

#literal_patternObject



429
430
431
432
433
# File 'lib/jade/ast.rb', line 429

def literal_pattern
  ->(literal) do
    Pattern::Literal[literal, literal.range]
  end
end

#maybe_ternaryObject

‘cond ? a : b` desugars to IfThenElse with single-expression bodies. The block form (`if cond then BODY else BODY end`) builds the same AST shape, so downstream passes don’t need to distinguish.



376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/jade/ast.rb', line 376

def maybe_ternary
  ->((cond, if_expr, else_expr)) do
    next cond if if_expr.nil?

    IfThenElse[
      cond,
      Body.new(expressions: [if_expr], range: if_expr.range),
      Body.new(expressions: [else_expr], range: else_expr.range),
      cond.range.begin...else_expr.range.end,
    ]
  end
end

#member_accessObject



275
276
277
278
279
280
281
282
283
# File 'lib/jade/ast.rb', line 275

def member_access
  ->(target, _dot, name) do
    MemberAccess[
      target,
      name,
      target.range.begin...name.range.end,
    ]
  end
end

#module_Object



351
352
353
354
355
356
357
358
359
360
# File 'lib/jade/ast.rb', line 351

def module_
  ->((module_parts, exposing, body)) do
    Module[
      module_parts.map(&:value).join('.'),
      exposing,
      body,
      module_parts.first.range.begin...(body.expressions.last.range.end),
    ]
  end
end

#placeholderObject



425
426
427
# File 'lib/jade/ast.rb', line 425

def placeholder
  ->(token) { Placeholder[token.range] }
end

#qualified_type_nameObject



216
217
218
219
220
221
# File 'lib/jade/ast.rb', line 216

def qualified_type_name
  ->((first, *rest)) do
    constants = [first] + rest
    QualifiedTypeName[constants.map(&:value), constants.first.range.begin...constants.last.range.end]
  end
end

#record_access_sugarObject



622
623
624
625
626
# File 'lib/jade/ast.rb', line 622

def record_access_sugar
  ->((dot, key)) do
    RecordAccessSugar[key.value, dot.range.begin...key.range.end]
  end
end

#record_fieldObject



599
600
601
602
603
# File 'lib/jade/ast.rb', line 599

def record_field
  ->((key, value)) do
    RecordField[key.value, value, key.range.begin...value.range.end]
  end
end

#record_field_patternObject



462
463
464
465
466
467
468
469
470
# File 'lib/jade/ast.rb', line 462

def record_field_pattern
  ->((identifier, _, pattern)) do
    Pattern::RecordField[
      identifier.value,
      pattern,
      identifier.range.begin...pattern.range.end,
    ]
  end
end

#record_literalObject



589
590
591
592
593
594
595
596
597
# File 'lib/jade/ast.rb', line 589

def record_literal
  ->((lbrace, fields_list, rbrace)) do
    RecordLiteral.new(
      fields: fields_list.items,
      trailing_comma: fields_list.trailing_comma,
      range: lbrace.range.begin...rbrace.range.end,
    )
  end
end

#record_patternObject



452
453
454
455
456
457
458
459
460
# File 'lib/jade/ast.rb', line 452

def record_pattern
  ->((lbrace, fields_list, r_brace)) do
    Pattern::Record.new(
      fields: fields_list.items,
      trailing_comma: fields_list.trailing_comma,
      range: lbrace.range.begin...r_brace.range.end,
    )
  end
end

#record_updateObject



605
606
607
608
609
610
611
612
613
614
# File 'lib/jade/ast.rb', line 605

def record_update
  ->((lbrace, variable_reference, _pipe, fields_list, rbrace)) do
    RecordUpdate.new(
      base: variable_reference,
      fields: fields_list.items,
      trailing_comma: fields_list.trailing_comma,
      range: lbrace.range.begin...rbrace.range.end,
    )
  end
end

#record_update_sugarObject



616
617
618
619
620
# File 'lib/jade/ast.rb', line 616

def record_update_sugar
  ->((dot, key, _assign)) do
    RecordUpdateSugar[key.value, dot.range.begin...key.range.end]
  end
end

#string_literalObject



94
95
96
97
98
99
100
# File 'lib/jade/ast.rb', line 94

def string_literal
  ->(tokens) do
    tokens => [open, token, close]

    Literal[token.value, token.range.begin...close.range.end]
  end
end

#struct_declarationObject



657
658
659
660
661
662
663
664
665
666
667
# File 'lib/jade/ast.rb', line 657

def struct_declaration
  ->((struct_token, name, type_params_list, record_type)) do
    StructDeclaration.new(
      name: name.value,
      type_params: type_params_list.items,
      record_type:,
      trailing_comma: type_params_list.trailing_comma,
      range: struct_token.range.begin...record_type.range.end,
    )
  end
end

#tupleObject



502
503
504
505
506
507
508
509
510
# File 'lib/jade/ast.rb', line 502

def tuple
  ->((lparen_token, first, rest_list, rparen_token)) do
    Tuple.new(
      items: [first, *rest_list.items],
      trailing_comma: rest_list.trailing_comma,
      range: lparen_token.range.begin...rparen_token.range.end,
    )
  end
end

#tuple_patternObject



472
473
474
475
476
477
478
479
480
# File 'lib/jade/ast.rb', line 472

def tuple_pattern
  ->((lparen_token, first, rest_list, rparen_token)) do
    Pattern::Tuple.new(
      patterns: [first, *rest_list.items],
      trailing_comma: rest_list.trailing_comma,
      range: lparen_token.range.begin...rparen_token.range.end,
    )
  end
end

#type_applicationObject



229
230
231
232
233
234
235
236
237
238
# File 'lib/jade/ast.rb', line 229

def type_application
  ->((constructor, args_list, rparen)) do
    TypeApplication.new(
      constructor:,
      args: args_list.items,
      trailing_comma: args_list.trailing_comma,
      range: constructor.range.begin...(rparen || constructor).range.end,
    )
  end
end

#type_declarationObject



285
286
287
288
289
290
291
292
293
294
295
# File 'lib/jade/ast.rb', line 285

def type_declaration
  ->((type_token, name, type_params_list, variants)) do
    TypeDeclaration.new(
      name: name.value,
      type_params: type_params_list.items,
      variants:,
      trailing_comma: type_params_list.trailing_comma,
      range: type_token.range.begin...variants.last.range.end,
    )
  end
end

#type_functionObject



240
241
242
243
244
245
246
247
248
249
# File 'lib/jade/ast.rb', line 240

def type_function
  ->((params, return_type)) do
    case params
    in [TypeUnit => unit]
      TypeFunction[[], return_type, unit.range.begin...return_type.range.end]
    else
      TypeFunction[params, return_type, params.first.range.begin...return_type.range.end]
    end
  end
end

#type_nameObject



199
200
201
202
203
# File 'lib/jade/ast.rb', line 199

def type_name
  ->(token) do
    TypeName[token.value, token.range]
  end
end

#type_paramObject



297
298
299
300
301
# File 'lib/jade/ast.rb', line 297

def type_param
  ->(identifier) do
    TypeParam[identifier.value, identifier.range]
  end
end

#type_recordObject



205
206
207
208
209
210
211
212
213
214
# File 'lib/jade/ast.rb', line 205

def type_record
  ->((lbrace, row_var, fields_list, rbrace)) do
    TypeRecord.new(
      fields: fields_list.items.map { |(identifier, type)| [identifier.value, type] }.to_h,
      row_var:,
      trailing_comma: fields_list.trailing_comma,
      range: lbrace.range.begin...rbrace.range.end,
    )
  end
end

#type_tupleObject



512
513
514
515
516
517
518
519
520
# File 'lib/jade/ast.rb', line 512

def type_tuple
  ->((lparen_token, first, rest_list, rparen_token)) do
    TypeTuple.new(
      items: [first, *rest_list.items],
      trailing_comma: rest_list.trailing_comma,
      range: lparen_token.range.begin...rparen_token.range.end,
    )
  end
end

#type_varObject



223
224
225
226
227
# File 'lib/jade/ast.rb', line 223

def type_var
  ->(token) do
    TypeVar[token.value, token.range]
  end
end

#variable_referenceObject



139
140
141
142
143
144
145
146
# File 'lib/jade/ast.rb', line 139

def variable_reference
  ->(identifier) do
    VariableReference[
      identifier.value,
      identifier.range,
    ]
  end
end

#variant_declarationObject



303
304
305
306
307
308
309
310
311
312
# File 'lib/jade/ast.rb', line 303

def variant_declaration
  ->((name, args_list)) do
    VariantDeclaration.new(
      name: name.value,
      args: args_list.items,
      trailing_comma: args_list.trailing_comma,
      range: name.range.begin...(args_list.items.last || name).range.end,
    )
  end
end

#wildcard_patternObject



419
420
421
422
423
# File 'lib/jade/ast.rb', line 419

def wildcard_pattern
  ->(token) do
    Pattern::Wildcard[token.range]
  end
end