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+



4912
4913
4914
4915
4916
4917
4918
4919
# File 'lib/HDLRuby/hruby_low.rb', line 4912

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

#typeObject (readonly)

Gets the type of the expression.

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



4909
4910
4911
# File 'lib/HDLRuby/hruby_low.rb', line 4909

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

#cloneObject

Clones the expression (deeply)

Raises:



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

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.



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

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

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



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

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.



4985
4986
4987
4988
4989
4990
4991
4992
# File 'lib/HDLRuby/hruby_low.rb', line 4985

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)


4925
4926
4927
4928
4929
# File 'lib/HDLRuby/hruby_low.rb', line 4925

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

#hashObject

Hash function.



4932
4933
4934
# File 'lib/HDLRuby/hruby_low.rb', line 4932

def hash
    return [@type].hash
end

#immutable?Boolean

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

Returns:

  • (Boolean)


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

def immutable?
    false
end

#leftvalue?Boolean

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

Returns:

  • (Boolean)


4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
# File 'lib/HDLRuby/hruby_low.rb', line 4937

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)


4957
4958
4959
# File 'lib/HDLRuby/hruby_low.rb', line 4957

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

#statementObject

Get the statement of the expression.



4995
4996
4997
4998
4999
5000
5001
# File 'lib/HDLRuby/hruby_low.rb', line 4995

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_highObject

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_namesObject

Get the port names for visualization from the expression.



5072
5073
5074
5075
5076
5077
5078
# File 'lib/HDLRuby/hruby_viz.rb', line 5072

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)


5004
5005
5006
5007
# File 'lib/HDLRuby/hruby_low.rb', line 5004

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