Class: Idl::IntLiteralAst
- Includes:
- Rvalue
- Defined in:
- lib/idl/ast.rb
Overview
represents an integer literal
Instance Method Summary collapse
-
#initialize(input, interval) ⇒ IntLiteralAst
constructor
A new instance of IntLiteralAst.
-
#to_idl ⇒ String
Return valid IDL representation of the node (and its subtree).
-
#type(symtab) ⇒ Type
Given a specific symbol table, return the type of this node.
-
#type_check(symtab) ⇒ void
type check this node and all children.
-
#unsigned_value ⇒ Integer
The unsigned value of this literal (i.e., treating it as unsigned even if the signed specifier is present).
-
#value(symtab) ⇒ Object
Return the compile-time-known value of the node.
-
#values(symtab) ⇒ Array<Integer>, ...
included
from Rvalue
Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.
- #width(symtab) ⇒ Object
Constructor Details
#initialize(input, interval) ⇒ IntLiteralAst
Returns a new instance of IntLiteralAst.
4298 4299 4300 4301 |
# File 'lib/idl/ast.rb', line 4298 def initialize(input, interval) super(input, interval, EMPTY_ARRAY) @types = [nil, nil] end |
Instance Method Details
#to_idl ⇒ String
Return valid IDL representation of the node (and its subtree)
4483 |
# File 'lib/idl/ast.rb', line 4483 def to_idl = text_value |
#type(symtab) ⇒ Type
Given a specific symbol table, return the type of this node.
Should not be called until #type_check is called with the same arguments
4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 |
# File 'lib/idl/ast.rb', line 4321 def type(symtab) cache_idx = symtab.mxlen >> 6 # 0 = 32, 1 = 64 return @types[cache_idx] unless @types[cache_idx].nil? case text_value.delete("_") when /^((XLEN)|([0-9]+))?'(s?)([bodh]?)(.*)$/ # verilog-style literal width = ::Regexp.last_match(1) signed = ::Regexp.last_match(4) memoize = true if width.nil? || width == "XLEN" width = symtab.mxlen memoize = false end qualifiers = signed == "s" ? [:signed, :const] : [:const] t = Type.new(:bits, width: width.to_i, qualifiers:) @types[cache_idx] = t if memoize t when /^0([bdx]?)([0-9a-fA-F]*)(s?)$/ # C++-style literal signed = ::Regexp.last_match(3) qualifiers = signed == "s" ? [:signed, :const] : [:const] type = Type.new(:bits, width: width(symtab), qualifiers:) @types[cache_idx] = type type when /^([0-9]*)(s?)$/ # basic decimal signed = ::Regexp.last_match(2) qualifiers = signed == "s" ? [:signed, :const] : [:const] type = Type.new(:bits, width: width(symtab), qualifiers:) @types[cache_idx] = type type else internal_error "Unhandled int value" end end |
#type_check(symtab) ⇒ void
4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 |
# File 'lib/idl/ast.rb', line 4304 def type_check(symtab) if text_value.delete("_") =~ /^((XLEN)|([0-9]+))?'(s?)([bodh]?)(.*)$/ # verilog-style literal width = ::Regexp.last_match(1) value_text = ::Regexp.last_match(6) if width.nil? || width == "XLEN" width = symtab.mxlen memoize = false end # ensure we actually have enough bits to represent the value type_error("#{value_text} cannot be represented in #{width} bits") if unsigned_value.bit_length > width.to_i end end |
#unsigned_value ⇒ Integer
Returns the unsigned value of this literal (i.e., treating it as unsigned even if the signed specifier is present).
4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 |
# File 'lib/idl/ast.rb', line 4431 def unsigned_value # return @unsigned_value unless @unsigned_value.nil? case text_value.delete("_") when /^((XLEN)|([0-9]+))?'(s?)([bodh]?)(.*)$/ # verilog-style literal radix_id = ::Regexp.last_match(5) value = ::Regexp.last_match(6) radix_id = "d" if radix_id.empty? case radix_id when "b" value.to_i(2) when "o" value.to_i(8) when "d" value.to_i(10) when "h" value.to_i(16) end when /^0([bdx]?)([0-9a-fA-F]*)(s?)$/ # C++-style literal radix_id = ::Regexp.last_match(1) value = ::Regexp.last_match(2) radix_id = "o" if radix_id.empty? # @unsigned_value = case radix_id when "b" value.to_i(2) when "o" value.to_i(8) when "d" value.to_i(10) when "x" value.to_i(16) end when /^([0-9]*)(s?)$/ # basic decimal value = ::Regexp.last_match(1) # @unsigned_value = value.to_i(10) value.to_i(10) else internal_error "Unhandled int value '#{text_value}'" end end |
#value(symtab) ⇒ Object
Return the compile-time-known value of the node
4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 |
# File 'lib/idl/ast.rb', line 4400 def value(symtab) # return @value unless @value.nil? if text_value.delete("_") =~ /^((XLEN)|([0-9]+))?'(s?)([bodh]?)(.*)$/ # verilog-style literal width = ::Regexp.last_match(1) signed = ::Regexp.last_match(4) memoize = true if width.nil? || width == "XLEN" width = symtab.mxlen memoize = false end v = if !signed.empty? && ((unsigned_value >> (width.to_i - 1)) == 1) -(2**width.to_i - unsigned_value) else unsigned_value end # @value = v if memoize v else # @value = unsigned_value unsigned_value end end |
#values(symtab) ⇒ Array<Integer>, ... Originally defined in module Rvalue
Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined
For most AstNodes, this will just be a single-entry array
#width(symtab) ⇒ Object
4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 |
# File 'lib/idl/ast.rb', line 4362 def width(symtab) # return @width unless @width.nil? text_value_no_underscores = text_value.delete("_") case text_value_no_underscores when /^((XLEN)|([0-9]+))?'(s?)([bodh]?)(.*)$/ # verilog-style literal width = ::Regexp.last_match(1) memoize = true if width.nil? || width == "XLEN" width = symtab.mxlen memoize = false end # @width = width if memoize width when /^0([bdx]?)([0-9a-fA-F]*)(s?)$/ signed = ::Regexp.last_match(3) width = signed == "s" ? value(symtab).bit_length + 1 : value(symtab).bit_length width = 1 if width.zero? # happens when the literal is '0' # @width = width width when /^([0-9]*)(s?)$/ signed = ::Regexp.last_match(3) width = signed == "s" ? value(symtab).bit_length + 1 : value(symtab).bit_length width = 1 if width.zero? # happens when the literal is '0' # @width = width width else internal_error "No match on int literal" end end |