Il 27/12/2017 15:05, Sven Barth via fpc-devel ha scritto:

No matter the syntax that might be chosen for this it will likely be sufficient to handle that feature by an absolutevarsym with a boolean flag or something like that. The difference to an ordinary absolute variable appears to be too small to warrant a new sym type.


After struggling sometime to find out the best way to implement the based feature without adding a new keyword, I found that the syntax:

aVar: anyType ABSOLUTE somePTR^;

can be implemented with minimal changes.

Attached the patch which does the trick, and which works like the old proven one.

It doesn't support *implicit* dereferencing, because I've left untouched the code which filters it out. One could remove the filtering for consistency, but I don't like very much the idea: the aim of such a feature is to provide a more readable and understandable code, not the opposite.

Giuliano

diff --git a/compiler/pdecvar.pas b/compiler/pdecvar.pas
index 1c828f5..5d67d28 100644
--- a/compiler/pdecvar.pas
+++ b/compiler/pdecvar.pas
@@ -61,7 +61,7 @@ implementation
        fmodule,htypechk,
        { pass 1 }
        node,pass_1,aasmbase,aasmdata,
-       ncon,nset,ncnv,nld,nutils,
+       ncon,nset,ncnv,nld,nutils,nmem,
        { codegen }
        ngenutil,
        { parser }
@@ -1133,11 +1133,13 @@ implementation
           abssym : tabsolutevarsym;
           pt,hp  : tnode;
           st     : tsymtable;
+          isBased: boolean;
           {$if defined(i386) or defined(i8086)}
           tmpaddr : int64;
           {$endif defined(i386) or defined(i8086)}
         begin
           abssym:=nil;
+          isBased:= false;
           { only allowed for one var }
           vs:=tabstractvarsym(sc[0]);
           if sc.count>1 then
@@ -1146,6 +1148,15 @@ implementation
             Message(parser_e_initialized_not_for_external);
           { parse the rest }
           pt:=expr(true);
+          { Support for absolute deref -
+          syntax:
+          sym: type ABSOLUTE ptr^;
+          }
+          if pt.nodetype=derefn then begin
+            pt := tderefnode(pt).left; // let's find the actual pointer
+            if pt.nodetype=loadn then  // and check that it's valid
+              isBased:= true;
+            end;
           { check allowed absolute types }
           if (pt.nodetype=stringconstn) or
             (is_constcharnode(pt)) then
@@ -1257,6 +1268,7 @@ implementation
                   abssym:=cabsolutevarsym.create(vs.realname,vs.vardef);
                   abssym.fileinfo:=vs.fileinfo;
                   abssym.abstyp:=tovar;
+                  abssym.isBased:= isBased;
                   abssym.ref:=node_to_propaccesslist(pt);
 
                   { if the sizes are different, can't be a regvar since you }
diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas
index 6d972de..ecc0533 100644
--- a/compiler/pexpr.pas
+++ b/compiler/pexpr.pas
@@ -3016,11 +3016,17 @@ implementation
                       begin
                         p1:=nil;
                         propaccesslist_to_node(p1,nil,tabsolutevarsym(srsym).ref);
+                        if tabsolutevarsym(srsym).isBased then
+                          p1 := cderefnode.create(p1);
                         p1:=ctypeconvnode.create(p1,tabsolutevarsym(srsym).vardef);
                         include(p1.flags,nf_absolute);
                       end
                     else
+                      begin
+                      if tabsolutevarsym(srsym).isBased then
+                        p1 := cderefnode.create(p1);
                       p1:=cloadnode.create(srsym,srsymtable);
+                    end;
                   end;
 
                 staticvarsym,
diff --git a/compiler/symsym.pas b/compiler/symsym.pas
index d522314..86bc007 100644
--- a/compiler/symsym.pas
+++ b/compiler/symsym.pas
@@ -316,6 +316,7 @@ interface
       tabsolutevarsym = class(tabstractvarsym)
       public
          abstyp  : absolutetyp;
+         isBased : boolean;
          asmname : pshortstring;
          addroffset : PUint;
          ref     : tpropaccesslist;
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to