4

Good day,

TValue is a Delphi-2010 and up RTTI feature.

Following on from my earlier question, I had tried to make recurrent function to return a TValue as a n-dimensional. matrix(2D, 3D, 4D...)

for example, this procedure will show a n-dimensional matrix(it will list all elements from a n-dimensional matrix as TValue variable):

Procedure Show(X:TValue);
var i:integer;
begin
   if x.IsArray then
   begin
      for i:=0 to x.GetArrayLength-1 do
          show(x.GetArrayElement(i));
      writeln;
   end else
   write(x.ToString,' ');

end;

I don't understand how to create a function to create from a TValue an n-dimensional matrix. For example i need a Function CreateDynArray(Dimensions:array of integer; Kind:TTypeKind):TValue; and the function will return a TValue which is a dynamic array how contain the dimenssions for example:

Return=CreateDynArray([2,3],tkInteger); will return a TValue as tkDynArray and if i will show(Return) will list

0 0 0
0 0 0

Is not terminated. From a TValue i try to create a DynArray with n-dimensions

Procedure CreateArray(var Value:TValue; NewDimmension:integer; NewValue2Kind:TTypeKind; NewValue2:TValue; IsLast:Boolean);
var i:integer;
NewValue:TValue;
len:Longint;
begin
   If Value.IsArray then// we have components in this dimension
   begin
       for i:=0 to Value.GetArrayLength-1 do// list all
       begin
            NewValue:=Value.GetArrayElement[i];
            CreateArray(newValue,NewDimension,NewValue2Kind,NewValue2,IsLast);
            Value.SetArrayElement(i,NewValue);
       end;
   end;
end else
begin
      if isLast then
      begin
         len:=NewDimension;
         DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len); //set length to NewDimension
         for i:=0 to NewDimension-1 do //Fill all with 0
           Value.SetArrayElement(i,NewValue2);
      end else
      begin
         len:=NewDimension;
         DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len);//I will create len TValues
      end;
end;



var Index:array of integer;
    Value:TValue;
    ValuKind:TTypeKind;
......
......
....
Case token of
   tokInt:
   begin
        ValueKind:=tkInteger;
        Value:=0;   
   end;
 .....
 end;

 Index:=GetIndexFromSintacticTree;//for example if i have int[20][30] index=[20,30]
 for i:=0 to high(index) do
 begin
    if i = high(index) then CreateArray(Variable.Value,Index[i],ValueKind,Value,True)
    else CreateArray(Variable.Value,Index[i],ValueKind,Value,False)
    //Variable.Value is TValue
 end;
 //first TValue have 1 element, after that it will have 20 elements, and after that will have 20*30 elements

The ideea

Thank you very much, and have a nice day!

8
  • What is TValue? What has RTTI have to do with it? Which version of Delphi do you have? Commented Dec 30, 2010 at 13:52
  • 1
    There is a new version for Reflection since Delphi 2010, with this new RTTI theoretic you can do anything. Commented Dec 30, 2010 at 13:59
  • It's quite hard to find the motivation to get into this question given that it is hard to see why anyone would want to do this. Is there some underlying motivation that goes beyond your personal distaste for Delphi generics? Commented Dec 30, 2010 at 15:49
  • 1
    I had a software, it have about 15.000 lines code all with TValue, and arrays of TValue(it's like a scripting language). And it's hard to change now. And with generics you can't allocate dynamically new generics(not run time), and is a fatal problem. I have a question to you. Did you understood my task? Commented Dec 30, 2010 at 15:58
  • 2
    @David, @Golez: TValue is a new type added in Delphi 2010. It's a record capable of representing any value in the Delphi type system. Sort of like a Variant, but different. What the OP wants is to find a way to make a TValue hold a dynamic array of arbitrary dimensions and base type, defined at runtime. As Barry points out, this is difficult because of the way dynamic arrays work. Commented Dec 31, 2010 at 0:48

1 Answer 1

5

To create a dynamic array dynamically, you need a reference to its type info structure (PTypeInfo) to pass to DynArraySetLength; calling DynArraySetLength and passing a reference to a nil pointer is how you can create a new dynamic array. If the specific shape of dynamic array does not already exist in your Delphi program, there will be no specific PTypeInfo pointer that the compiler will generate for you. In this case, you would have to generate the corresponding PTypeInfo data structure yourself. This is possible, though tedious.

Frankly, I'd recommend you use a different structure than built-in Delphi dynamic arrays to represent arrays in your scripting language-like problem. In the long run it will probably be a lot less work than trying to dynamically generate the low-level RTTI data, which is more likely to change from version to version now that it has a much higher level abstraction in the Rtti unit.

Sign up to request clarification or add additional context in comments.

3 Comments

I really hope the format of TTypeInfo and TTypeData doesn't change, except to add new branches to the TTypeData union tree that fill in gaps in the existing RTTI. I've been doing a lot of theoretical work in the area of dynamic class and type generation in order to implement a scripting system that integrates seamlessly with compiled Delphi code through RTTI. I'm a week or two away from having a working POC compiler now, and it would be rather annoying to have to completely rework my type data generation code when a new version comes out.
@Mason It's less a case of completely changing, than having more data appended on the end. It's a real PITA to jam in extra data without breaking code. As it is, the RTTI format contributes a fairly substantial size penalty largely because its encoding can't be optimized much. It would be nice to consider something like e.g. .NET metadata tables, which use a conciser representation. Instead, Delphi RTTI is left with every xref taking up a minimum of 4 bytes, and frequently with redundant strings for names that could be pooled. But that can't happen within the current framework.
Fair enough. It's a real mess trying to write code to read RTTI structures because of all of the inline data arrays without a static size, meaning the compiler can't find the field that comes next and you need a bunch of pointer math. If your new format could get rid of that I'd be all for it, and I'd only need to rewrite my generation code once. The part that bugged me was when you said "from version to version," implying that there will (might) be format revamps with each new release, or a significant fraction of them. That would be a pain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.