Search code examples
tclxilinxvivado

Is everything really a string in TCL?


And what is it, if it isn't?

Everything I've read about TCL states that everything is just a string in it. There can be some other types and structures inside of an interpreter (for performance), but at TCL language level everything must behave just like a string. Or am I wrong?

I'm using an IDE for FPGA programming called Vivado. TCL automation is actively used there. (TCL version is still 8.5, if it helps) Vivado's TCL scripts rely on some kind of "object oriented" system. Web search doesn't show any traces of this system elsewhere. In this system objects are usually obtained from internal database with "get_*" commands. I can manipulate properties of these objects with commands like get_property, set_property, report_property, etc. But these objects seem to be something more than just a string. I'll try to illustrate:

> set vcu [get_bd_cells /vcu_0]
/vcu_0
> puts "|$vcu|"
|/vcu_0|
> report_property $vcu
Property                            Type    Read-only  Value
CLASS                               string  true       bd_cell
CONFIG.AXI_DEC_BASE0                string  false      0
<...>
> report_property "$vcu"
Property                            Type    Read-only  Value
CLASS                               string  true       bd_cell
CONFIG.AXI_DEC_BASE0                string  false      0
<...>

But:

> report_property "/vcu_0"
ERROR: [Common 17-58] '/vcu_0' is not a valid first class Tcl object.
> report_property {/vcu_0}
ERROR: [Common 17-58] '/vcu_0' is not a valid first class Tcl object.
> report_property /vcu_0
ERROR: [Common 17-58] '/vcu_0' is not a valid first class Tcl object.
> puts |$vcu|
|/vcu_0|
> report_property [string range $vcu 0 end]
ERROR: [Common 17-58] '/vcu_0' is not a valid first class Tcl object.

So, my question is: what exactly is this "valid first class Tcl object"?

Clarification: This question might seem like asking for help with Vivado scripting, but it is not. (I was even in doubt about adding [vivado] to tags.) I can just live and script with these mystic objects. But it would be quite useful (for me, and maybe for others) to better understand their inner workings. Is this "object system" a dirty hack? Or is it a perfectly valid TCL usage? If it's valid, where can I read about it? If it is a hack, how is it (or can it be) implemented? Where exactly does string end and object starts?

Related: A part of this answer can be considered as an opinion in favor of the "hack" version, but it is quite shallow in a sense of my question.


Solution

  • A first class Tcl value is a sequence of characters, where those characters are drawn from the Basic Multilingual Plane of the Unicode specification. (We're going to relax that BMP restriction in a future version, but that's not yet in a version we'd recommend for use.) All other values are logically considered to be subtypes of that. For example, binary strings have the characters come from the range [U+000000, U+0000FF], and integers are ASCII digit sequences possibly preceded by a small number of prefixes (e.g., - for a negative number).

    In terms of implementation, there's more going on. For example, integers are usually implemented using 64-bit binary values in the endianness that your system uses (but can be expanded to bignums when required) inside a value boxing mechanism, and the string version of the value is generated on demand and cached while the integer value doesn't change. Floating point numbers are IEEE double-precision floats. Lists are internally implemented as an array of values (with smartness for handling allocation). Dictionaries are hash tables with linked lists hanging off each of the hash buckets. And so on. THESE ARE ALL IMPLEMENTATION DETAILS! As a programmer, you can and should typically ignore them totally. What you need to know is that if two values are the same, they will have the same string, and if they have the same string, they are the same in the other interpretation. (Values with different strings can also be equal for other reasons: for example, 0xFF is numerically equal to 255 — hex vs decimal — but they are not string equal. Tcl's true natural equality is string equality.)

    True mutable entities are typically represented as named objects: only the name is a Tcl value. This is how Tcl's procedures, classes, I/O system, etc. all work. You can invoke operations on them, but you can only see inside to a limited extent.