Class: HDLRuby::Low::Expression

Inherits:
Object
  • Object
show all
Includes:
Hparent, Low2Symbol
Defined in:
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_viz.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_with_bool.rb,
lib/HDLRuby/hruby_low_without_select.rb,
lib/HDLRuby/hruby_low_without_namespace.rb,
lib/HDLRuby/hruby_low_without_subsignals.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_low2sym.rb,
lib/HDLRuby/hruby_low2hdr.rb,
lib/HDLRuby/hruby_low2c.rb

Overview

Describes an expression.

NOTE: this is an abstract class which is not to be used directly.

Direct Known Subclasses

Cast, Concat, Operation, Ref, StringE, Value

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 Hparent

#absolute_ref, #hierarchy, #no_parent!, #scope

Methods included from Low2Symbol

#to_sym

Constructor Details

#initialize(type = Void) ⇒ Expression

Creates a new Expression with type



4890
4891
4892
4893
4894
4895
4896
4897
# File 'lib/HDLRuby/hruby_low.rb', line 4890

def initialize(type = Void)
    # Check and set the type.
    if type.is_a?(Type) then
        @type = type
    else
        raise AnyError, "Invalid class for a type: #{type.class}."
    end
end

Instance Attribute Details

#type ⇒ Object (readonly)

Gets the type of the expression.

def type # By default: the void type. return Void end



4887
4888
4889
# File 'lib/HDLRuby/hruby_low.rb', line 4887

def type
  @type
end

Instance Method Details

#boolean? ⇒ Boolean

Tells if the expression is boolean.

Returns:



109
110
111
# File 'lib/HDLRuby/hruby_low_with_bool.rb', line 109

def boolean?
    return false
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.



566
567
568
569
570
571
572
573
574
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 566

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)
            node.set_type!(node.type.break_types!(types))
        end
    end
end

#clone ⇒ Object

Clones the expression (deeply)

Raises:



4990
4991
4992
4993
# File 'lib/HDLRuby/hruby_low.rb', line 4990

def clone
    raise AnyError,
          "Internal error: clone not defined for class: #{self.class}"
end

#each_node(&ruby_block) ⇒ Object Also known as: each_expression

Iterates over the expression children if any.



4947
4948
4949
# File 'lib/HDLRuby/hruby_low.rb', line 4947

def each_node(&ruby_block)
    # By default: no child.
end

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



4954
4955
4956
4957
4958
4959
4960
# File 'lib/HDLRuby/hruby_low.rb', line 4954

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 that's all.
end

#each_ref_deep(&ruby_block) ⇒ Object

Iterates over all the references encountered in the expression.

NOTE: do not iterate inside the references.



4965
4966
4967
4968
4969
4970
4971
4972
# File 'lib/HDLRuby/hruby_low.rb', line 4965

def each_ref_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_ref_deep) unless ruby_block
    # puts "each_ref_deep for Expression which is:#{self}"
    # A ruby block?
    # If the expression is a reference, applies ruby_block on it.
    ruby_block.call(self) if self.is_a?(Ref)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:



4905
4906
4907
4908
4909
# File 'lib/HDLRuby/hruby_low.rb', line 4905

def eql?(obj)
    return false unless obj.is_a?(Expression)
    return false unless @type.eql?(obj.type)
    return true
end

#explicit_types(type = nil) ⇒ Object

Explicit the types conversions in the expression where type is the expected type of the condition if any.



232
233
234
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 232

def explicit_types(type = nil)
    raise "Should implement explicit_types for class #{self.class}."
end

#extract_selects_to!(selects) ⇒ Object

Extract the Select expressions and put them into selects



252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/HDLRuby/hruby_low_without_select.rb', line 252

def extract_selects_to!(selects)
    # Recurse on the sub expressions.
    self.map_expressions! {|expr| expr.extract_selects_to!(selects) }
    # Treat case of select.
    if self.is_a?(Select) then
        # Create the signal replacing self.
        sig = SignalI.new(HDLRuby.uniq_name,self.type)
        # Add the self with replacing sig to the extracted selects
        selects << [self,sig]
        # Create the signal replacing self.
        blk = self.statement.block
        if blk then
            # Add the signal in the block.
            blk.add_inner(sig)
        else
            # No block, this is a connection, add the signal in the
            # socpe
            self.statement.scope.add_inner(sig)
        end
        # And return a reference to it.
        return RefName.new(sig.type,RefThis.new,sig.name)
    end
    return self
end

#fix_scope_refnames!(scopes) ⇒ Object

Fix the references names using scopes given in +scopes + list (they are marked to be deleted).



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

def fix_scope_refnames!(scopes)
    # By default: recurse.
    self.map_nodes! do |node|
        node.fix_scope_refnames!(scopes)
    end
    return self
end

#hash ⇒ Object

Hash function.



4912
4913
4914
# File 'lib/HDLRuby/hruby_low.rb', line 4912

def hash
    return [@type].hash
end

#immutable? ⇒ Boolean

Tells if the expression is immutable (cannot be written.)

Returns:



4942
4943
4944
# File 'lib/HDLRuby/hruby_low.rb', line 4942

def immutable?
    false
end

#leftvalue? ⇒ Boolean

Tells if the expression is a left value of an assignment.

Returns:



4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
# File 'lib/HDLRuby/hruby_low.rb', line 4917

def leftvalue?
    # Maybe its the left of a left value.
    if parent.respond_to?(:leftvalue?) && parent.leftvalue? then
        # Yes so it is also a left value if it is a sub ref.
        if parent.respond_to?(:ref) then
            # It might nor be a sub ref.
            # return parent.ref.eql?(self)
            return parent.ref.equal?(self)
        else
            # It is necessarily a sub ref (case of RefConcat for now).
            return true
        end
    end
    # No, therefore maybe it is directly a left value.
    return (parent.is_a?(Transmit) || parent.is_a?(Connection)) &&
        # parent.left.eql?(self)
        parent.left.equal?(self)
end

#map_nodes!(&ruby_block) ⇒ Object Also known as: map_expressions!

Maps on the children.



1321
1322
1323
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1321

def map_nodes!(&ruby_block)
    # By default, nothing to do.
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.



1333
1334
1335
1336
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1333

def replace_expressions!(node2rep)
    # By default, nothing to do.
    return {}
end

#replace_names!(former, nname) ⇒ Object

Replaces recursively former name by nname until it is redeclared.



554
555
556
557
558
559
560
561
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 554

def replace_names!(former,nname)
    # By default: try to replace the name recursively.
    self.each_node_deep do |node|
        if node.respond_to?(:name) && node.name == former then
            node.set_name!(nname)
        end
    end
end

#rightvalue? ⇒ Boolean

Tells if the expression is a right value.

Returns:



4937
4938
4939
# File 'lib/HDLRuby/hruby_low.rb', line 4937

def rightvalue?
    return !self.leftvalue?
end

#set_type!(type) ⇒ Object

Sets the type.



1311
1312
1313
1314
1315
1316
1317
1318
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1311

def set_type!(type)
    # Check and set the type.
    if type.is_a?(Type) then
        @type = type
    else
        raise AnyError, "Invalid class for a type: #{type.class}."
    end
end

#signal2subs! ⇒ Object

Decompose the hierarchical signals in the statements.



230
231
232
233
234
235
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 230

def signal2subs!
    # puts "signal2subs! for expr=#{self}"
    # Recurse on the subexpressions.
    self.map_expressions!(&:signal2subs!)
    return self
end

#statement ⇒ Object

Get the statement of the expression.



4975
4976
4977
4978
4979
4980
4981
# File 'lib/HDLRuby/hruby_low.rb', line 4975

def statement
    if self.parent.is_a?(Statement)
        return self.parent
    else
        return self.parent.statement
    end
end

#to_c(res, level = 0) ⇒ Object

Generates the C text of the equivalent HDLRuby code. level is the hierachical level of the object. def to_c(level = 0)

Raises:



2119
2120
2121
2122
# File 'lib/HDLRuby/hruby_low2c.rb', line 2119

def to_c(res,level = 0)
    # Should never be here.
    raise AnyError, "Internal error: to_c should be implemented in class :#{self.class}"
end

#to_c_expr(res, level = 0) ⇒ Object

Generates the C text for an expression access to the expression, default case. level is the hierachical level of the object.



2127
2128
2129
2130
2131
2132
# File 'lib/HDLRuby/hruby_low2c.rb', line 2127

def to_c_expr(res,level = 0)
    res << "({"
    self.to_c(res,level+1)
    res << (" " * ((level+1)*3))
    res << "pop();})"
end

#to_hdr(level = 0) ⇒ Object

Generates the text of the equivalent hdr text. level is the hierachical level of the object.

Raises:



556
557
558
559
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 556

def to_hdr(level = 0)
    # Should never be here.
    raise AnyError, "Internal error: to_hdr should be implemented in class :#{self.class}"
end

#to_high ⇒ Object

Creates a new high expression.

Raises:



404
405
406
407
# File 'lib/HDLRuby/hruby_low2high.rb', line 404

def to_high
    raise AnyError,
          "Internal error: to_high is not defined for class: #{self.class}"
end

#to_vhdl(level = 0) ⇒ Object

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

Raises:



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

def to_vhdl(level = 0)
    # Should never be here.
    raise AnyError, "Internal error: to_vhdl should be implemented in class :#{self.class}"
end

#to_viz_names ⇒ Object

Get the port names for visualization from the expression.



5186
5187
5188
5189
5190
5191
5192
# File 'lib/HDLRuby/hruby_viz.rb', line 5186

def to_viz_names
  res = []
  self.each_node do |expr|
    res += expr.to_viz_names
  end
  return res
end

#use_name?(*names) ⇒ Boolean

Tell if the expression includes a signal whose name is one of names.

Returns:



4984
4985
4986
4987
# File 'lib/HDLRuby/hruby_low.rb', line 4984

def use_name?(*names)
    # By default nothing.
    return false
end

#width ⇒ Object

Gets the bit width of the expression.



4900
4901
4902
# File 'lib/HDLRuby/hruby_low.rb', line 4900

def width
    return @type.width
end