Class: HDLRuby::Low::When

Inherits:
Object
  • Object
show all
Includes:
Hparent, Low2Symbol
Defined in:
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2seq.rb,
lib/HDLRuby/hruby_low2sym.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_cleanup.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_with_var.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_bool2select.rb,
lib/HDLRuby/hruby_low_without_select.rb,
lib/HDLRuby/hruby_low_without_namespace.rb,
lib/HDLRuby/hruby_low_casts_without_expression.rb

Overview

Extends the When class with functionality for extracting expressions from cast.

Direct Known Subclasses

High::When

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary collapse

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#scope

Constructor Details

#initialize(match, statement) ⇒ When

Creates a new when for a casde statement that executes +statement+ on +match+.



2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
# File 'lib/HDLRuby/hruby_low.rb', line 2985

def initialize(match,statement)
    # Checks the match.
    unless match.is_a?(Expression)
        raise AnyError, "Invalid class for a case match: #{match.class}"
    end
    # Checks statement.
    unless statement.is_a?(Statement)
        raise AnyError,
              "Invalid class for a statement: #{statement.class}"
    end
    # Set the match.
    @match = match
    # Set the statement.
    @statement = statement
    # And set their parents.
    match.parent = statement.parent = self
end

Instance Attribute Details

#matchObject (readonly)

The value to match.



2979
2980
2981
# File 'lib/HDLRuby/hruby_low.rb', line 2979

def match
  @match
end

#statementObject (readonly)

The statement to execute in in case of match.



2981
2982
2983
# File 'lib/HDLRuby/hruby_low.rb', line 2981

def statement
  @statement
end

Instance Method Details

#add_blocks_code(res, level) ⇒ Object

Adds the c code of the blocks to +res+ at +level+



1168
1169
1170
# File 'lib/HDLRuby/hruby_low2c.rb', line 1168

def add_blocks_code(res,level)
    self.statement.add_blocks_code(res,level)
end

#blocks2seq!Object

Converts the par sub blocks to seq.



135
136
137
138
139
# File 'lib/HDLRuby/hruby_low2seq.rb', line 135

def blocks2seq!
    # Convert the statement.
    self.statement.blocks2seq!
    return self
end

#boolean_in_assign2select!Object

Converts booleans in assignments to select operators.



93
94
95
96
97
98
99
100
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 93

def boolean_in_assign2select!
    # No need to apply on the match!
    # # Apply on the match.
    # self.set_match!(self.match.boolean_in_assign2select)
    # Apply on the statement.
    self.statement.boolean_in_assign2select!
    return self
end

#break_types!(types) ⇒ Object

Breaks the hierarchical types into sequences of type definitions. Assumes to_upper_space! has been called before. +types+ include the resulting types.



594
595
596
597
598
599
600
601
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 594

def break_types!(types)
    self.each_node do |node|
        # Need to break only in the case of a cast.
        if node.is_a?(Cast) then
            node.type.break_types!(types)
        end
    end
end

#casts_without_expression!Object

Extracts the expressions from the casts.



91
92
93
94
95
96
97
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 91

def casts_without_expression!
    # Apply on the match.
    self.set_match!(self.match.casts_without_expression)
    # Apply on the statement.
    self.statement.casts_without_expression!
    return self
end

#cloneObject

Clones the When (deeply)



3017
3018
3019
# File 'lib/HDLRuby/hruby_low.rb', line 3017

def clone
    return When.new(@match.clone,@statement.clone)
end

#delete_related!(*names) ⇒ Object

Deletes the elements related to one of +names+: either they have one of the names or they use an element with these names. NOTE: only delete actual instantiated elements, types or systemTs are left as is.



816
817
818
819
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 816

def delete_related!(*names)
    # Recurse on the statement.
    @statement.delete_related!(*names)
end

#delete_unless!(keep) ⇒ Object

Removes the signals and corresponding assignments whose name is not in +keep+.



145
146
147
148
# File 'lib/HDLRuby/hruby_low_cleanup.rb', line 145

def delete_unless!(keep)
    # Recurse on the statement.
    self.statement.delete_unless!(keep)
end

#each_block(&ruby_block) ⇒ Object

Iterates over the sub blocks.



3022
3023
3024
3025
3026
3027
3028
# File 'lib/HDLRuby/hruby_low.rb', line 3022

def each_block(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_block) unless ruby_block
    # A ruby block?
    # Apply it on the statement if it is a block.
    ruby_block.call(@statement) if @statement.is_a?(Block)
end

#each_block_deep(&ruby_block) ⇒ Object

Iterates over all the blocks contained in the current block.



3031
3032
3033
3034
3035
3036
3037
# File 'lib/HDLRuby/hruby_low.rb', line 3031

def each_block_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_block_deep) unless ruby_block
    # A ruby block?
    # Recurse on the statement.
    @statement.each_block_deep(&ruby_block)
end

#each_node(&ruby_block) ⇒ Object

Interates over the children.



3049
3050
3051
3052
3053
3054
3055
3056
# File 'lib/HDLRuby/hruby_low.rb', line 3049

def each_node(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node) unless ruby_block
    # A ruby block?
    # Appy it on the children.
    ruby_block.call(@match)
    ruby_block.call(@statement)
end

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



3059
3060
3061
3062
3063
3064
3065
3066
3067
# File 'lib/HDLRuby/hruby_low.rb', line 3059

def each_node_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # And recurse on the children
    @match.each_node_deep(&ruby_block)
    @statement.each_node_deep(&ruby_block)
end

#each_statement_deep(&ruby_block) ⇒ Object

Iterates over all the stamements of the block and its sub blocks.



3040
3041
3042
3043
3044
3045
3046
# File 'lib/HDLRuby/hruby_low.rb', line 3040

def each_statement_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_statement_deep) unless ruby_block
    # A ruby block?
    # Recurse on the statement.
    @statement.each_statement_deep(&ruby_block)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


3004
3005
3006
3007
3008
3009
# File 'lib/HDLRuby/hruby_low.rb', line 3004

def eql?(obj)
    return false unless obj.is_a?(When)
    return false unless @match.eql?(obj.match)
    return false unless @statement.eql?(obj.statement)
    return true
end

#explicit_types!(type) ⇒ Object

Explicit the types conversions in the when where +type+ is the type of the selecting value.



116
117
118
119
120
121
122
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 116

def explicit_types!(type)
    # Recurse on the match, it must be of type.
    self.set_match!(self.match.explicit_types(type))
    # Recurse on the statement.
    self.statement.explicit_types!
    return self
end

#extract_declares!Object

Extract the declares from the scope and returns them into an array.

NOTE: do not recurse into the sub scopes or behaviors!



578
579
580
581
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 578

def extract_declares!
    # Recurse on the statement.
    return self.statement.extract_declares!
end

#extract_selects!Object

Extract the Select expressions.

NOTE: work on the match only.



187
188
189
190
191
# File 'lib/HDLRuby/hruby_low_without_select.rb', line 187

def extract_selects!
    selects = []
    self.set_match!(self.match.extract_selects_to!(selects))
    return selects
end

#hashObject

Hash function.



3012
3013
3014
# File 'lib/HDLRuby/hruby_low.rb', line 3012

def hash
    return [@match,@statement].hash
end

#map_nodes!(&ruby_block) ⇒ Object

Maps on the children (including the match).



778
779
780
781
782
783
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 778

def map_nodes!(&ruby_block)
    @match = ruby_block.call(@match)
    @match.parent = self unless @match.parent
    @statement = ruby_block.call(@statement)
    @statement.parent = self unless @statement.parent
end

#mix?(mode = nil) ⇒ Boolean

Tell if there is a mix block. +mode+ is the mode of the upper block.

Returns:

  • (Boolean)


143
144
145
146
# File 'lib/HDLRuby/hruby_low2seq.rb', line 143

def mix?(mode = nil)
    # Check the statement.
    return statement.mix?(mode)
end

#replace_expressions!(node2rep) ⇒ Object

Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement. Returns the actually replaced nodes and their corresponding replacement.

NOTE: the replacement is duplicated.



791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 791

def replace_expressions!(node2rep)
    # First recurse on the children.
    res = {}
    self.each_node do |node|
        res.merge!(node.replace_expressions!(node2rep))
    end
    # Is there a replacement to do on the value?
    rep = node2rep[self.match]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = self.match
        # node.set_parent!(nil)
        self.set_match!(rep)
        # And register the replacement.
        res[node] = rep
    end

    return res
end

#replace_names!(former, nname) ⇒ Object

Replaces recursively +former+ name by +nname+ until it is redeclared.



584
585
586
587
588
589
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 584

def replace_names!(former,nname)
    # Recurse on the match.
    self.match.replace_names!(former,nname)
    # Recurse on the statement.
    self.statement.replace_names!(former,nname)
end

#set_match!(match) ⇒ Object

Sets the match.



753
754
755
756
757
758
759
760
761
762
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 753

def set_match!(match)
    # Checks the match.
    unless match.is_a?(Expression)
        raise AnyError, "Invalid class for a case match: #{match.class}"
    end
    # Set the match.
    @match = match
    # And set their parents.
    match.parent = self
end

#set_statement!(statement) ⇒ Object

Sets the statement.



765
766
767
768
769
770
771
772
773
774
775
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 765

def set_statement!(statement)
    # Checks statement.
    unless statement.is_a?(Statement)
        raise AnyError,
              "Invalid class for a statement: #{statement.class}"
    end
    # Set the statement.
    @statement = statement
    # And set their parents.
    statement.parent = self
end

#to_c(level = 0) ⇒ Object

Generates the C text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
# File 'lib/HDLRuby/hruby_low2c.rb', line 1153

def to_c(level = 0)
    # The result string.
    res = " " * level*3
    # Generate the match.
    res << "case " << self.match.to_c(level+1) << ": {\n"
    # Generate the statement.
    res << self.statement.to_c(level+1)
    # Adds a break
    res << " " * (level+1)*3 << "break;\n"
    res << " " * level*3 << "}\n"
    # Returns the result.
    return res
end

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/HDLRuby/hruby_low2high.rb', line 381

def to_high(level = 0)
    # The result string.
    res = " " * (level*3)
    # Generate the match.
    res << "hwhen " << self.match.to_high(level+1) << " do\n"
    # Generate the statement.
    res << self.statement.to_high(level+1)
    # Close the when.
    res << " " * (level*3) << "end\n"
    # Returns the result.
    return res
end

#to_upper_space!Object

Moves the declarations to the upper namespace.



570
571
572
573
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 570

def to_upper_space!
    # Recurse on the statement.
    self.statement.to_upper_space!
end

#to_vhdl(vars, type, level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code ensuring the match is of +type+. +vars+ is the list of the variables and +level+ is the hierachical level of the object.



945
946
947
948
949
950
951
952
953
954
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 945

def to_vhdl(vars,type,level = 0)
    # The result string.
    res = " " * (level*3)
    # Generate the match.
    res << "when " << Low2VHDL.to_type(type,self.match) << " =>\n"
    # Generate the statement.
    res << self.statement.to_vhdl(vars,level+1)
    # Returns the result.
    return res
end

#top_blockObject

Gets the top block, i.e. the first block of the current behavior.



3070
3071
3072
# File 'lib/HDLRuby/hruby_low.rb', line 3070

def top_block
    return self.parent.is_a?(Behavior) ? self : self.parent.top_block
end

#use_name?(*names) ⇒ Boolean

Tell if the statement includes a signal whose name is one of +names+. NOTE: for the when check only the match.

Returns:

  • (Boolean)


3076
3077
3078
# File 'lib/HDLRuby/hruby_low.rb', line 3076

def use_name?(*names)
    return @match.use_name?(*name)
end

#with_var(upper = nil) ⇒ Object

Converts to a variable-compatible case where +upper+ is the upper block if any.

NOTE: the result is a new case.



299
300
301
# File 'lib/HDLRuby/hruby_low_with_var.rb', line 299

def with_var(upper = nil)
    return When.new(self.match.clone,self.statement.with_var(upper))
end