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



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

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

#bindObject



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

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



445
446
447
448
449
# File 'lib/jade/ast.rb', line 445

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

#bodyObject



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/jade/ast.rb', line 168

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



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

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



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

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



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

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

#char_literalObject



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

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

#constructor_patternObject



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

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



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

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

#curried_constructorObject



159
160
161
162
163
164
165
166
# File 'lib/jade/ast.rb', line 159

def curried_constructor
  ->(constant) do
    CurriedConstructor[
      constant.value,
      constant.range,
    ]
  end
end

#expose_allObject



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

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

#expose_asObject



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

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

#expose_listObject



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

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



543
544
545
546
547
# File 'lib/jade/ast.rb', line 543

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

#expose_typeObject



571
572
573
574
575
# File 'lib/jade/ast.rb', line 571

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

#expose_type_expandObject



577
578
579
580
581
# File 'lib/jade/ast.rb', line 577

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

#expose_valueObject



565
566
567
568
569
# File 'lib/jade/ast.rb', line 565

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

#function_callObject



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

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



182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/jade/ast.rb', line 182

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



197
198
199
200
201
202
203
204
205
206
207
# File 'lib/jade/ast.rb', line 197

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

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

#groupingObject



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

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

#if_then_elseObject



372
373
374
375
376
377
378
379
380
381
# File 'lib/jade/ast.rb', line 372

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



679
680
681
682
683
684
685
686
687
688
689
# File 'lib/jade/ast.rb', line 679

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



691
692
693
694
695
696
697
698
699
700
701
702
703
704
# File 'lib/jade/ast.rb', line 691

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



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

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



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

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



706
707
708
709
710
711
712
713
714
715
# File 'lib/jade/ast.rb', line 706

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



717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
# File 'lib/jade/ast.rb', line 717

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



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

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

#interop_import_declarationObject



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

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



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

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

#keyed_callObject



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

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



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

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



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

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



532
533
534
535
536
537
538
539
540
541
# File 'lib/jade/ast.rb', line 532

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



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

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



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

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



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

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



439
440
441
442
443
# File 'lib/jade/ast.rb', line 439

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.



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

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



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

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

#module_Object



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

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



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

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

#qualified_type_nameObject



226
227
228
229
230
231
# File 'lib/jade/ast.rb', line 226

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



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

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

#record_fieldObject



609
610
611
612
613
# File 'lib/jade/ast.rb', line 609

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

#record_field_patternObject



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

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

#record_literalObject



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

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



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

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



615
616
617
618
619
620
621
622
623
624
# File 'lib/jade/ast.rb', line 615

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



626
627
628
629
630
# File 'lib/jade/ast.rb', line 626

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

#string_literalObject



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

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

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

#struct_declarationObject



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

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



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

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



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

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



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

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



295
296
297
298
299
300
301
302
303
304
305
# File 'lib/jade/ast.rb', line 295

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



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

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



209
210
211
212
213
# File 'lib/jade/ast.rb', line 209

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

#type_paramObject



307
308
309
310
311
# File 'lib/jade/ast.rb', line 307

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

#type_recordObject



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

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



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

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



233
234
235
236
237
# File 'lib/jade/ast.rb', line 233

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

#variable_referenceObject



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

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

#variant_declarationObject



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

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



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

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