Class: IgniterLang::ParsedProgram

Inherits:
Object
  • Object
show all
Defined in:
lib/igniter_lang/parser.rb

Overview


ParsedProgram builder (public API)


Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ast:, source:, source_path:) ⇒ ParsedProgram

Returns a new instance of ParsedProgram.



1664
1665
1666
1667
1668
1669
1670
# File 'lib/igniter_lang/parser.rb', line 1664

def initialize(ast:, source:, source_path:)
  require "digest"
  @ast         = ast
  @source_path = source_path
  @source_hash = "sha256:#{Digest::SHA256.hexdigest(source)}"
  @errors      = ast.fetch("parse_errors", [])
end

Instance Attribute Details

#astObject (readonly)

Returns the value of attribute ast.



1654
1655
1656
# File 'lib/igniter_lang/parser.rb', line 1654

def ast
  @ast
end

#errorsObject (readonly)

Returns the value of attribute errors.



1654
1655
1656
# File 'lib/igniter_lang/parser.rb', line 1654

def errors
  @errors
end

#source_hashObject (readonly)

Returns the value of attribute source_hash.



1654
1655
1656
# File 'lib/igniter_lang/parser.rb', line 1654

def source_hash
  @source_hash
end

Class Method Details

.parse(source, source_path: "<stdin>") ⇒ Object



1656
1657
1658
1659
1660
1661
1662
# File 'lib/igniter_lang/parser.rb', line 1656

def self.parse(source, source_path: "<stdin>")
  require "digest"
  tokens = Lexer.new(source).tokenize
  parser = Parser.new(tokens)
  ast    = parser.parse
  new(ast: ast, source: source, source_path: source_path)
end

Instance Method Details

#grammar_versionObject



1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
# File 'lib/igniter_lang/parser.rb', line 1701

def grammar_version
  decimal_type_ref = lambda { |n|
    n.is_a?(Hash) && n["kind"] == "type_ref" && n["name"] == "Decimal"
  }
  return "assumptions-v0" if @ast.fetch("assumptions", []).any? ||
                             @ast.fetch("contracts", []).any? { |c|
                               c.fetch("body", []).any? { |n| n.is_a?(Hash) && n["kind"] == "uses_assumptions" }
                             }
  return "olap-point-v0" if @ast.fetch("olap_points", []).any?

  has_decimal = @ast.fetch("contracts", []).any? { |c|
    c.fetch("body", []).any? { |node|
      node.is_a?(Hash) && (
        decimal_type_ref.call(node["type_annotation"]) ||
        decimal_type_ref.call(node.fetch("type_annotation", nil))
      )
    }
  } || @ast.fetch("types", []).any? { |t| decimal_type_ref.call(t["alias"]) }
  return "decimal-v0" if has_decimal

  return "spark-pipeline-v0" if @ast.fetch("pipelines", []).any? ||
                                @ast.fetch("contracts", []).any? { |c|
                                  c.fetch("body", []).any? { |n|
                                    n.is_a?(Hash) && n["scoped_by"]
                                  }
                                }

  return "polymorphic-v0" if @ast.fetch("traits", []).any? ||
                             @ast.fetch("impls", []).any? ||
                             @ast.fetch("contract_shapes", []).any? ||
                             @ast.fetch("contracts", []).any? { |contract| contract.fetch("type_params", []).any? }

  "0.1.0"
end

#to_hObject



1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
# File 'lib/igniter_lang/parser.rb', line 1680

def to_h
  {
    "kind"            => "parsed_program",
    "source_path"     => @source_path,
    "source_hash"     => @source_hash,
    "grammar_version" => grammar_version,
    "module"          => @ast["module"],
    "imports"         => @ast["imports"],
    "traits"          => @ast["traits"],
    "impls"           => @ast["impls"],
    "contract_shapes" => @ast["contract_shapes"],
    "contracts"       => @ast["contracts"],
    "types"           => @ast["types"],
    "functions"       => @ast["functions"],
    "pipelines"       => @ast.fetch("pipelines", []),
    "olap_points"     => @ast.fetch("olap_points", []),
    "assumptions"     => @ast.fetch("assumptions", []),
    "parse_errors"    => @errors
  }
end

#to_json(**opts) ⇒ Object



1676
1677
1678
# File 'lib/igniter_lang/parser.rb', line 1676

def to_json(**opts)
  JSON.generate(to_h, **opts)
end

#valid?Boolean

Returns:

  • (Boolean)


1672
1673
1674
# File 'lib/igniter_lang/parser.rb', line 1672

def valid?
  @errors.empty?
end