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_low2c.rb,
lib/HDLRuby/hruby_low2hdr.rb,
lib/HDLRuby/hruby_low2sym.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.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

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 Low2Symbol

#to_sym

Methods included from Hparent

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

Constructor Details

#initialize(type = Void) ⇒ Expression

Creates a new Expression with type



4947
4948
4949
4950
4951
4952
4953
4954
# File 'lib/HDLRuby/hruby_low.rb', line 4947

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



4944
4945
4946
# File 'lib/HDLRuby/hruby_low.rb', line 4944

def type
  @type
end

Instance Method Details

#boolean? ⇒ Boolean

Tells if the expression is boolean.

Returns:

  • (Boolean)


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:



5045
5046
5047
5048
# File 'lib/HDLRuby/hruby_low.rb', line 5045

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.



5002
5003
5004
# File 'lib/HDLRuby/hruby_low.rb', line 5002

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

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



5009
5010
5011
5012
5013
5014
5015
# File 'lib/HDLRuby/hruby_low.rb', line 5009

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.



5020
5021
5022
5023
5024
5025
5026
5027
# File 'lib/HDLRuby/hruby_low.rb', line 5020

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:

  • (Boolean)


4960
4961
4962
4963
4964
# File 'lib/HDLRuby/hruby_low.rb', line 4960

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.



4967
4968
4969
# File 'lib/HDLRuby/hruby_low.rb', line 4967

def hash
    return [@type].hash
end

#immutable? ⇒ Boolean

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

Returns:

  • (Boolean)


4997
4998
4999
# File 'lib/HDLRuby/hruby_low.rb', line 4997

def immutable?
    false
end

#leftvalue? ⇒ Boolean

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

Returns:

  • (Boolean)


4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
# File 'lib/HDLRuby/hruby_low.rb', line 4972

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:

  • (Boolean)


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

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.



5030
5031
5032
5033
5034
5035
5036
# File 'lib/HDLRuby/hruby_low.rb', line 5030

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:



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

def to_hdr(level = 0)
    # Should never be here.
    raise AnyError, "Internal error: to_high 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.



4879
4880
4881
4882
4883
4884
4885
# File 'lib/HDLRuby/hruby_viz.rb', line 4879

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:

  • (Boolean)


5039
5040
5041
5042
# File 'lib/HDLRuby/hruby_low.rb', line 5039

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