晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。   林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。   见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝)   既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。   南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。 sh-3ll

HOME


sh-3ll 1.0
DIR:/opt/alt/ruby33/share/ruby/prism/
Upload File :
Current File : //opt/alt/ruby33/share/ruby/prism/desugar_compiler.rb
# frozen_string_literal: true

module Prism
  # DesugarCompiler is a compiler that desugars Ruby code into a more primitive
  # form. This is useful for consumers that want to deal with fewer node types.
  class DesugarCompiler < MutationCompiler
    # @@foo &&= bar
    #
    # becomes
    #
    # @@foo && @@foo = bar
    def visit_class_variable_and_write_node(node)
      desugar_and_write_node(node, ClassVariableReadNode, ClassVariableWriteNode, node.name)
    end

    # @@foo ||= bar
    #
    # becomes
    #
    # defined?(@@foo) ? @@foo : @@foo = bar
    def visit_class_variable_or_write_node(node)
      desugar_or_write_defined_node(node, ClassVariableReadNode, ClassVariableWriteNode, node.name)
    end

    # @@foo += bar
    #
    # becomes
    #
    # @@foo = @@foo + bar
    def visit_class_variable_operator_write_node(node)
      desugar_operator_write_node(node, ClassVariableReadNode, ClassVariableWriteNode, node.name)
    end

    # Foo &&= bar
    #
    # becomes
    #
    # Foo && Foo = bar
    def visit_constant_and_write_node(node)
      desugar_and_write_node(node, ConstantReadNode, ConstantWriteNode, node.name)
    end

    # Foo ||= bar
    #
    # becomes
    #
    # defined?(Foo) ? Foo : Foo = bar
    def visit_constant_or_write_node(node)
      desugar_or_write_defined_node(node, ConstantReadNode, ConstantWriteNode, node.name)
    end

    # Foo += bar
    #
    # becomes
    #
    # Foo = Foo + bar
    def visit_constant_operator_write_node(node)
      desugar_operator_write_node(node, ConstantReadNode, ConstantWriteNode, node.name)
    end

    # $foo &&= bar
    #
    # becomes
    #
    # $foo && $foo = bar
    def visit_global_variable_and_write_node(node)
      desugar_and_write_node(node, GlobalVariableReadNode, GlobalVariableWriteNode, node.name)
    end

    # $foo ||= bar
    #
    # becomes
    #
    # defined?($foo) ? $foo : $foo = bar
    def visit_global_variable_or_write_node(node)
      desugar_or_write_defined_node(node, GlobalVariableReadNode, GlobalVariableWriteNode, node.name)
    end

    # $foo += bar
    #
    # becomes
    #
    # $foo = $foo + bar
    def visit_global_variable_operator_write_node(node)
      desugar_operator_write_node(node, GlobalVariableReadNode, GlobalVariableWriteNode, node.name)
    end

    # @foo &&= bar
    #
    # becomes
    #
    # @foo && @foo = bar
    def visit_instance_variable_and_write_node(node)
      desugar_and_write_node(node, InstanceVariableReadNode, InstanceVariableWriteNode, node.name)
    end

    # @foo ||= bar
    #
    # becomes
    #
    # @foo || @foo = bar
    def visit_instance_variable_or_write_node(node)
      desugar_or_write_node(node, InstanceVariableReadNode, InstanceVariableWriteNode, node.name)
    end

    # @foo += bar
    #
    # becomes
    #
    # @foo = @foo + bar
    def visit_instance_variable_operator_write_node(node)
      desugar_operator_write_node(node, InstanceVariableReadNode, InstanceVariableWriteNode, node.name)
    end

    # foo &&= bar
    #
    # becomes
    #
    # foo && foo = bar
    def visit_local_variable_and_write_node(node)
      desugar_and_write_node(node, LocalVariableReadNode, LocalVariableWriteNode, node.name, node.depth)
    end

    # foo ||= bar
    #
    # becomes
    #
    # foo || foo = bar
    def visit_local_variable_or_write_node(node)
      desugar_or_write_node(node, LocalVariableReadNode, LocalVariableWriteNode, node.name, node.depth)
    end

    # foo += bar
    #
    # becomes
    #
    # foo = foo + bar
    def visit_local_variable_operator_write_node(node)
      desugar_operator_write_node(node, LocalVariableReadNode, LocalVariableWriteNode, node.name, node.depth)
    end

    private

    # Desugar `x &&= y` to `x && x = y`
    def desugar_and_write_node(node, read_class, write_class, *arguments)
      AndNode.new(
        read_class.new(*arguments, node.name_loc),
        write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location),
        node.operator_loc,
        node.location
      )
    end

    # Desugar `x += y` to `x = x + y`
    def desugar_operator_write_node(node, read_class, write_class, *arguments)
      write_class.new(
        *arguments,
        node.name_loc,
        CallNode.new(
          0,
          read_class.new(*arguments, node.name_loc),
          nil,
          node.operator_loc.slice.chomp("="),
          node.operator_loc.copy(length: node.operator_loc.length - 1),
          nil,
          ArgumentsNode.new(0, [node.value], node.value.location),
          nil,
          nil,
          node.location
        ),
        node.operator_loc.copy(start_offset: node.operator_loc.end_offset - 1, length: 1),
        node.location
      )
    end

    # Desugar `x ||= y` to `x || x = y`
    def desugar_or_write_node(node, read_class, write_class, *arguments)
      OrNode.new(
        read_class.new(*arguments, node.name_loc),
        write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location),
        node.operator_loc,
        node.location
      )
    end

    # Desugar `x ||= y` to `defined?(x) ? x : x = y`
    def desugar_or_write_defined_node(node, read_class, write_class, *arguments)
      IfNode.new(
        node.operator_loc,
        DefinedNode.new(nil, read_class.new(*arguments, node.name_loc), nil, node.operator_loc, node.name_loc),
        node.operator_loc,
        StatementsNode.new([read_class.new(*arguments, node.name_loc)], node.location),
        ElseNode.new(
          node.operator_loc,
          StatementsNode.new(
            [write_class.new(*arguments, node.name_loc, node.value, node.operator_loc, node.location)],
            node.location
          ),
          node.operator_loc,
          node.location
        ),
        node.operator_loc,
        node.location
      )
    end
  end
end