Re: [fpc-devel] An extension of fpc language: the BASED construct
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
Re: [fpc-devel] An extension of fpc language: the BASED construct
Am 27.12.2017 00:54 schrieb "Giuliano Colla": Il 26/12/2017 18:26, Sven Barth via fpc-devel ha scritto: Am 26.12.2017 13:33 schrieb "Giuliano Colla" : If the idea is not rejected, then a number of refinements (which I'm ready to implement) are required to make the feature generally available: My following remarks are independent of an eventual acceptance of the feature : - All architectures should be supported (now it's only for x86_64 - symcpu.pas). It might be possible to implement this in a platform independent way that might simply need to expand the capabilites of "absolute". The feature in itself is platform independent. The only catch is that in pdecvar.pas (where variable declaration is handled) there's a per platform hook for each symbol type, in order to allow for special handling of some features. For consistency I did follow the same rule, which is used for all the other declarations, disregarding whether they're platform independent or not. As a consequence, for each supported platform you must add in its specific symcpu.pas a type entry: tcpubasedvarsym = class(tbasedvarsym) end; tcpubasedvarsymclass = class of tcpubasedvarsym; and a line of code: cbasedvarsym:=tcpubasedvarsym; As this is tedious, I've only done it for the platform I'm using (x86_64/symcpu.pas). To deploy the feature, the same lines must be added in each platform symcpu.pas unit. There's no more that that. 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. - It should be decided if internal error # which currently keep the same number of the nearby ABSOLUTE internal error should be given new values. Internal errors shall always be unique as they are used to find the error location, even for copy pasted code. What's the rule to avoiding clashes? I gathered sort of MMDD## is it correct? Correct. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
Hello folks, As described on my site programming.sirrida.de/pascal_proposals.html#offset I would propose a slightly more general approach to the theme. In contrast to the presented solution my offsets are separated from the base pointer. Calculations with offsets, e.g.: TYPE tr_rec = RECORD a,b: integer; END; VAR v: tr_rec; o: OFFSET tr_rec OF integer; BEGIN o := OFFSET(tr_rec,a); v.[o] := v.b; ... END. An probably better alternative syntax for "OFFSET(tr_rec,a)" could be "tr_rec @ a" thereby overloading the address operator without using a new keyword. The symbol pair ".[" denotes access "at offset" and should be applicable on records, objects, classes and arrays. This allows fields to be addressed similar to array elements. It might help to speed up multiple array accesses because the multiplication can happen earlier. In the implementation in assembler the offset is simply added to the base address. In contrast to general offsets, these specialized offsets can not be added, subtracted or even scaled. The WITH statement could be enhanced to handle offsets as well. You may emulate the functionality as follows: TYPE tp_int = ^integer; ta_8u = ARRAY [0..maxint] OF byte; tpa_8u = ^ta_8u; tpr_rec = ^tr_rec; VAR v: tr_rec; o: integer; BEGIN o := integer(@tpr_rec(nil)^.a); // o := OFFSET(tr_rec,a); tp_int(@tpa_8u(@v)^[o])^ := v.b; // v.[o] := v.b; … END. As you see, there are some nasty things necessary for the emulation: We assume that nil is zero and we use a cast from pointer to integer, and there are some more castings. An alternative approach using "extended syntax" (pointer arithmetic) is a little better. My proposal however is clean and type-safe and does not need any castings. The ARRAY [0..maxint] is an example of a substitute of a half open array definition. Best regards Jasper Neumann ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
On 26/12/17 23:15, Giuliano Colla wrote: Il 26/12/2017 14:27, Mark Morgan Lloyd ha scritto:> What does gdb (and possibly other debuggers) make of this? What currently gdb tells (and any other debugger would tell) is : No symbol "Item" in current context. Once the appropriate entries are implemented in the debugger symbol table, it will behave like it does in similar conditions, i.e. displaying a value referenced by a pointer. I didn't mention in my ToDo list because I'm a bit lazy, but this too has to be done. I'm getting uncomfortable with the amount of "magic" required here. Is it really appropriate to declare Item as a variable, when it's > really more akin to a macro? It's not different from the declarations: myString: string;myObject: TObject; where your declaration only reserves a pointer, while the actual string or object will be instantiated only at run time. Item is a variable, whose location isn't known at compile time, but will be known only at run time. Except that you've already said above that "Item" doesn't actually exist, while "myString" does even if the compiler etc. knows that it's to be implicitly dereferenced. I'd suggest that this would be better approached either as a generalisation of managed types- strings and the rest, or as a final resolution of the "with" controversy including full consideration of the scope issues. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
Il 26/12/2017 18:26, Sven Barth via fpc-devel ha scritto: Am 26.12.2017 13:33 schrieb "Giuliano Colla">: If the idea is not rejected, then a number of refinements (which I'm ready to implement) are required to make the feature generally available: My following remarks are independent of an eventual acceptance of the feature : - All architectures should be supported (now it's only for x86_64 - symcpu.pas). It might be possible to implement this in a platform independent way that might simply need to expand the capabilites of "absolute". The feature in itself is platform independent. The only catch is that in pdecvar.pas (where variable declaration is handled) there's a per platform hook for each symbol type, in order to allow for special handling of some features. For consistency I did follow the same rule, which is used for all the other declarations, disregarding whether they're platform independent or not. As a consequence, for each supported platform you must add in its specific symcpu.pas a type entry: tcpubasedvarsym = class(tbasedvarsym) end; tcpubasedvarsymclass = class of tcpubasedvarsym; and a line of code: cbasedvarsym:=tcpubasedvarsym; As this is tedious, I've only done it for the platform I'm using (x86_64/symcpu.pas). To deploy the feature, the same lines must be added in each platform symcpu.pas unit. There's no more that that. - It should be decided if to make the feature generally available, or conditioned by an {$IFDEF FPCHASBASED} - It should be decided if the feature should be available in all modes or only in a selected number of modes (what of TurboPascal Mode or Delphi Mode?). Rule of thumb: new features added as a separate mode switch, no FPC_HAS_* define necessary as by definition this can be done with version checks (there is only one trunk version, namely the current one). - It should be decided if error messages should be specific for the BASED construct or common to the ABSOLUTE one, slightly rephrasing the error message. Might be one or the other depending on the message. - It should be decided if internal error # which currently keep the same number of the nearby ABSOLUTE internal error should be given new values. Internal errors shall always be unique as they are used to find the error location, even for copy pasted code. What's the rule to avoiding clashes? I gathered sort of MMDD## is it correct? Giuliano ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
Il 26/12/2017 14:27, Mark Morgan Lloyd ha scritto: What does gdb (and possibly other debuggers) make of this? What currently gdb tells (and any other debugger would tell) is : No symbol "Item" in current context. Once the appropriate entries are implemented in the debugger symbol table, it will behave like it does in similar conditions, i.e. displaying a value referenced by a pointer. I didn't mention in my ToDo list because I'm a bit lazy, but this too has to be done. Is it really appropriate to declare Item as a variable, when it's really more akin to a macro? It's not different from the declarations: myString: string; myObject: TObject; where your declaration only reserves a pointer, while the actual string or object will be instantiated only at run time. Item is a variable, whose location isn't known at compile time, but will be known only at run time. Giuliano ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
In that case, if the functionality is going to be included, the best course of action might be to restore pre 2.4.0 behaviour, add the ability to use explicit dereference, and bind it to a separate mode switch. Binding it to a mode switch solves the Delphi compatibility reason for removing it. Allowing both explicit and implicit dereference solves the consistency reason for removing it. And as Sven said, allowing absolute with expressions would be preferable to introducing a new keyword. > -Original Message- > From: fpc-devel [mailto:fpc-devel-boun...@lists.freepascal.org] On > Behalf Of Karoly Balogh (Charlie/SGR) > Sent: Wednesday, 27 December 2017 03:43 > To: FPC developers' list> Subject: Re: [fpc-devel] *** GMX Spamverdacht *** An extension of > fpc language: the BASED construct > > HI, > > On Tue, 26 Dec 2017, Thorsten Engler wrote: > > > > Item: BYTE BASED ItemPtr; > > > > Ignoring any other considerations for now, I would have at least > used > > a logical extension derived from already supported syntax: > > > > Item: Byte absolute ItemPtr^; > > As far as I understand (I did not try) this was once supported, but > explicitly removed by FPC 2.4.0 from Absolute keyword dereferencing > is no longer allowed: > > http://wiki.freepascal.org/User_Changes_2.4.0#Absolute_variable_decl > arations > > As the reasoning there shows, it's a very slippery slope this, which > could open a can of worms, so careful people. :) > > Charlie > ___ > fpc-devel maillist - fpc-devel@lists.freepascal.org > http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
Am 26.12.2017 13:33 schrieb "Giuliano Colla": If the idea is not rejected, then a number of refinements (which I'm ready to implement) are required to make the feature generally available: My following remarks are independent of an eventual acceptance of the feature : - All architectures should be supported (now it's only for x86_64 - symcpu.pas). It might be possible to implement this in a platform independent way that might simply need to expand the capabilites of "absolute". - It should be decided if to make the feature generally available, or conditioned by an {$IFDEF FPCHASBASED} - It should be decided if the feature should be available in all modes or only in a selected number of modes (what of TurboPascal Mode or Delphi Mode?). Rule of thumb: new features added as a separate mode switch, no FPC_HAS_* define necessary as by definition this can be done with version checks (there is only one trunk version, namely the current one). - It should be decided if error messages should be specific for the BASED construct or common to the ABSOLUTE one, slightly rephrasing the error message. Might be one or the other depending on the message. - It should be decided if internal error # which currently keep the same number of the nearby ABSOLUTE internal error should be given new values. Internal errors shall always be unique as they are used to find the error location, even for copy pasted code. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
See: http://tutorial.modernpascal.com/?DataTypes I implemented INTEGER as 32bit, but, if FPC makes it 16bit only, I will go make the change right now. My end-users all know *DO NOT USE INTEGER* it's even in the license agreement. "It is only there for make code compatible w/ Delphi and FPC." I am still spending all my spare time to get MPC's tutorial site up to par with FPC - as I promote MPC as FPC's Script Engine. On Tue, Dec 26, 2017 at 8:50 AM, Ozz Nixonwrote: > I like the concept, I would like to ask that we do not support INTEGER as > a type, and be more specific by limiting to SHORTINT, SMALLINT, LONGINT, > INT64. That way code snippets are not confusing when you implement 16bit > INT logic on a 32bit INT environment. Because I do a lot of documentation > for n00bs in Pascal - the interchangeable INTEGER is probably one of > Borland's biggest mistakes with the grammar! I would love to see FPC make > the statement that the type INTEGER is 16bit only - deal with people > freaking out for a year or two, and move the language forward. Even the > INTEGER example here is assuming 16bit - which would be incorrect on 32bit > platforms in specific $MODE. (may have picked wrong wording, however, I > think everyone see's the point). > > Other than that, if FPC adds this, I will add it to Modern Pascal, so at > least the two products are supporting "BASED". > > On Tue, Dec 26, 2017 at 8:27 AM, Mark Morgan Lloyd < > markmll.fpc-de...@telemetry.co.uk> wrote: > >> On 26/12/17 12:45, Giuliano Colla wrote: >> >> /In short the BASED construct makes the C-style dereferencing operator >>> unnecessary, by moving dereferencing from code to declaration. >>> >>> In fpc this translates into code looking like this, in this trivial >>> example: >>> >>> var >>>I: BYTE; >>>I1: INTEGER; >>>ItemPtr: Pointer; >>>Item: BYTE BASED ItemPtr; >>>IntegerItem: INTEGER BASED ItemPtr; >>> >>>ItemPtr := @I; >>>Item := $41; >>> >>>ItemPtr := @I1; >>>IntegerItem := -32767; >>> >>> This code will load the BYTE value $41 into the variable I, and the >>> INTEGER value -32767 into the variable I1. >>> >> >> What does gdb (and possibly other debuggers) make of this? Is it really >> appropriate to declare Item as a variable, when it's really more akin to a >> macro? >> >> -- >> Mark Morgan Lloyd >> markMLl .AT. telemetry.co .DOT. uk >> >> [Opinions above are the author's, not those of his employers or >> colleagues] >> ___ >> fpc-devel maillist - fpc-devel@lists.freepascal.org >> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel >> > > ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
I like the concept, I would like to ask that we do not support INTEGER as a type, and be more specific by limiting to SHORTINT, SMALLINT, LONGINT, INT64. That way code snippets are not confusing when you implement 16bit INT logic on a 32bit INT environment. Because I do a lot of documentation for n00bs in Pascal - the interchangeable INTEGER is probably one of Borland's biggest mistakes with the grammar! I would love to see FPC make the statement that the type INTEGER is 16bit only - deal with people freaking out for a year or two, and move the language forward. Even the INTEGER example here is assuming 16bit - which would be incorrect on 32bit platforms in specific $MODE. (may have picked wrong wording, however, I think everyone see's the point). Other than that, if FPC adds this, I will add it to Modern Pascal, so at least the two products are supporting "BASED". On Tue, Dec 26, 2017 at 8:27 AM, Mark Morgan Lloyd < markmll.fpc-de...@telemetry.co.uk> wrote: > On 26/12/17 12:45, Giuliano Colla wrote: > > /In short the BASED construct makes the C-style dereferencing operator >> unnecessary, by moving dereferencing from code to declaration. >> >> In fpc this translates into code looking like this, in this trivial >> example: >> >> var >>I: BYTE; >>I1: INTEGER; >>ItemPtr: Pointer; >>Item: BYTE BASED ItemPtr; >>IntegerItem: INTEGER BASED ItemPtr; >> >>ItemPtr := @I; >>Item := $41; >> >>ItemPtr := @I1; >>IntegerItem := -32767; >> >> This code will load the BYTE value $41 into the variable I, and the >> INTEGER value -32767 into the variable I1. >> > > What does gdb (and possibly other debuggers) make of this? Is it really > appropriate to declare Item as a variable, when it's really more akin to a > macro? > > -- > Mark Morgan Lloyd > markMLl .AT. telemetry.co .DOT. uk > > [Opinions above are the author's, not those of his employers or colleagues] > ___ > fpc-devel maillist - fpc-devel@lists.freepascal.org > http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel > ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] An extension of fpc language: the BASED construct
On 26/12/17 12:45, Giuliano Colla wrote: /In short the BASED construct makes the C-style dereferencing operator unnecessary, by moving dereferencing from code to declaration. In fpc this translates into code looking like this, in this trivial example: var I: BYTE; I1: INTEGER; ItemPtr: Pointer; Item: BYTE BASED ItemPtr; IntegerItem: INTEGER BASED ItemPtr; ItemPtr := @I; Item := $41; ItemPtr := @I1; IntegerItem := -32767; This code will load the BYTE value $41 into the variable I, and the INTEGER value -32767 into the variable I1. What does gdb (and possibly other debuggers) make of this? Is it really appropriate to declare Item as a variable, when it's really more akin to a macro? -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[fpc-devel] An extension of fpc language: the BASED construct
Hi fpc developers, here enclosed a patch to the compiler (and ppudump) to support the BASED construct (PL/1 and PL/M style), together with a patch to Lazarus codetools in order to be able to use it with Lazarus IDE. For those unfamiliar with the BASED construct, here's a short description taken from Intel's PL/M-86 manual: Based Variables Sometimes a direct reference to a PL/M-86 data element is either impossible or inconvenient. This happens for example, when the location of a data element must remain unknown until it is computed ad run time. In such cases, it may be necessary to write PL/M-86 code to manipulate the locations of data elements themselves. To permit this type of manipulation PL/M-86 uses "based variables". A based variable is one that is pointed to by another variable called its "base". This means the base contains the address of the desired (based) variable. In short the BASED construct makes the C-style dereferencing operator unnecessary, by moving dereferencing from code to declaration. In fpc this translates into code looking like this, in this trivial example: var I: BYTE; I1: INTEGER; ItemPtr: Pointer; Item: BYTE BASED ItemPtr; IntegerItem: INTEGER BASED ItemPtr; ItemPtr := @I; Item := $41; ItemPtr := @I1; IntegerItem := -32767; This code will load the BYTE value $41 into the variable I, and the INTEGER value -32767 into the variable I1. In more formal terms, the Declaration section of the fpc manual should include a new path: >--Variable modifiers -- based -- pointer --> | | | | | | -- PUint _expression_ ---| | etc.. The main points are: It doesn't break anything. - I have thoroughly tested it in my private fpc versions since fpc 2.2.4 Nobody is forced to use it: whoever doesn't like it can simply ignore its existence. It provides a feature consistent with the general Pascal approach, to avoid whenever possible redundant dereferencing and typecasting, moving the tedious jobs from the developer to the compiler. It saves a number of C-style declarations, dereferencing and typecasting, and it provides a better type checking, making the code less error prone and much more readable and more "Pascalish". It's very useful in message passing techniques, where different message types are funnelled to a single endpoint. Typically such messages are records composed by a fixed header which tells about the message type, followed by a variable content. They can be found everywhere, from IPC to X11 interface to tcp/ip packets. I found it also useful in data entry applications, where different fields require different data types. The implementation is rather trivial: a BASED declaration is nothing else than an ABSOLUTE declaration with an added dereferencing. Therefore I've simply duplicated the code for the ABSOLUTE, with a minimal change in pexpr.pas, and minimal adaptations elsewhere. The enclosed patches are provided just to permit testing, evaluation and scrutiny from fpc maintainers. They only contain what is required for my personal usage. If the idea is not rejected, then a number of refinements (which I'm ready to implement) are required to make the feature generally available: - All architectures should be supported (now it's only for x86_64 - symcpu.pas). - It should be decided if to make the feature generally available, or conditioned by an {$IFDEF FPCHASBASED} - It should be decided if the feature should be available in all modes or only in a selected number of modes (what of TurboPascal Mode or Delphi Mode?). - It should be decided if error messages should be specific for the BASED construct or common to the ABSOLUTE one, slightly rephrasing the error message. - It should be decided if internal error # which currently keep the same number of the nearby ABSOLUTE internal error should be given new values. - Maybe something else which I failed to notice. I'd love to see my favourite programming language enriched by such a feature! Giuliano Index: nld.pas === --- nld.pas (revisione 37753) +++ nld.pas (copia locale) @@ -292,6 +292,8 @@ case symtableentry.typ of absolutevarsym :