Recent

Author Topic: Proposing 4 New Ideas - #2 Interjections  (Read 1666 times)

IndigoBoy83

  • New member
  • *
  • Posts: 9
Proposing 4 New Ideas - #2 Interjections
« on: March 22, 2019, 01:33:02 pm »
PAGE #2A - Introducing Interjections

The notion of interjections can be called the use of "non-generic code".

InterjectCode is a procedure which is compiled and executed *before* compile-time, that is, at precompile-time.  It outputs the code that resides in its "parameter space". 

Take the following snippet as example:

Code: Pascal  [Select][+][-]
  1. Program Test1;
  2. begin
  3.   InterjectCode( writeln('Cool!'); );
  4. end.

At precompile-time the above program Test1 precompiles to the following:

Code: Pascal  [Select][+][-]
  1. Program Test1;
  2. begin
  3.   writeln('Cool!');
  4. end.

It can then compile normally as usual.

Interjections are methods similar to functions, but do not return values, rather they return code.

They are made up of code too; which we call "compile code", unlike "runtime code" as everything else.

Unlike procedures they cannot be called at compile-time.  Rather, they are methods that have to do it before, at precompile-time. 

All interjections start of with the moniker "Interjection".
Then we give the name of the interjection.
They too may have a parameter list just like regular compile methods.
As precompile-time methods, they denote their boundaries using the words "start"/"stop" rather than the words "begin"/"end" for compile-time methods. 

A programmer may find himself inside of an "InterjectCode" call and want to "jump out" into the compiler.  One does that by using the following syntax: we write "***" to enter and exit compiler code.  We give below an example of this use with an interjection:

Code: Pascal  [Select][+][-]
  1. Program Test2;
  2.  
  3. Interjection TestMe( _str : string );
  4. start
  5.   InterjectCode(
  6.     writeln( 'The given string is ', _str );
  7.   );
  8. stop;
  9.  
  10. begin
  11.   InterjectCode( ***TestMe( 'Hello' );*** );
  12.   InterjectCode( ***TestMe( 'GoodBye' );*** );
  13. end.

At precompile-time the above program Test2 precompiles to the following:

Code: Pascal  [Select][+][-]
  1. Program Test2;
  2. begin
  3.   writeln( 'The given string is Hello' );
  4.   writeln( 'The given string is GoodBye' );
  5. end.

The following program takes the above Test2 and augments it to Test3, to demonstrate that we can "nest" interjections:

Code: Pascal  [Select][+][-]
  1. Program Test3;
  2.  
  3. Interjection TestMeAgain( _int : integer );
  4. start
  5.   if _int = 5 then
  6.     InterjectCode(
  7.       writeln( 'Thank you!  I like my strings in fives!' );
  8.     )
  9.   else
  10.     InterjectCode(
  11.       writeln( 'No thanks!  I like my strings in fives ONLY!' );
  12.     );
  13. stop;
  14.  
  15. Interjection TestMe( _str : string );
  16. start
  17.   InterjectCode(
  18.     writeln( 'The given string is ', _str );
  19.     InterjectCode( ***TestMeAgain( length(_str) );*** );
  20.   );
  21. stop;
  22.  
  23. begin
  24.   InterjectCode( ***TestMe( 'Hello' );*** );
  25.   InterjectCode( ***TestMe( 'GoodBye' );*** );
  26. end.

At precompile-time the above program Test3 precompiles to the following:

Code: Pascal  [Select][+][-]
  1. Program Test3;
  2. begin
  3.   writeln( 'The given string is Hello' );
  4.   writeln( 'Thank you!  I like my strings in fives!' );
  5.   writeln( 'The given string is GoodBye' );
  6.   writeln( 'No thanks!  I like my strings in fives ONLY!' );
  7. end.

------------------------------------------------------------------
PAGE #2B - Solving the object/class war

The following solves the problem of how to change between an "object" to a "class" in one fluent motion, using the idea of interjections.

By using interjections the programmer may decide, at compile-time, whether his records are objects or classes with the ease of changing the value of *only* one variable.

Notice: Below we use the notion of etypes, and the typeof function, which returns the type of the given parameter.

Code: Pascal  [Select][+][-]
  1. Program Ending_Object_Class_War;
  2.  
  3. interface
  4.  
  5. uses
  6.     Classes;
  7.  
  8. const
  9.      typeofrec : etype = object;  // Can be set to either object or class depending on programmers wish on compilation
  10.  
  11. implementation
  12.  
  13. Interjection MakeIt( var _x : typeofrec );
  14. start
  15.   case typeof(_x) of
  16.     object: InterjectCode( New(_x); );            
  17.     class: InterjectCode( _x.Create; );    
  18.   end;
  19. stop;
  20.  
  21. Interjection UnMakeIt( var _x : typeofrec );
  22. start
  23.   case typeof(_x) of
  24.     object: InterjectCode( Dispose(_x); );
  25.     class: InterjectCode( _x.Free; );
  26.   end;
  27. stop;
  28.  
  29. type
  30.     some_record_type = typeofrec
  31.       Procedure WriteItOut;
  32.     end;
  33.  
  34. Procedure some_record_type.WriteItOut;
  35. begin
  36.   writeln( 'Programmer can decide whether this "some_rec" is an object or class at compile-time with one easy switch of the value typeofrec!' );
  37.   writeln( 'Right now some_record_type is ', str(typeof(self)) );  // Outputs whether self is object or class
  38. end;
  39.  
  40. var
  41.    some_rec : some_record_type;
  42.  
  43. begin
  44.   InterjectCode( ***MakeIt( some_rec );*** );  // Makes some_rec as object/class
  45.   some_rec.WriteItOut;  // Writes message to screen
  46.   InterjectCode( ***UnMakeIt( some_rec );*** );  // UnMakes some_rec as object/class
  47. end.

If typeofrec equals "object" then the previous code precompiles to:

Code: Pascal  [Select][+][-]
  1. Program Ending_Object_Class_War;
  2.  
  3. interface
  4.  
  5. uses
  6.     Classes;
  7.  
  8. implementation
  9.  
  10. type
  11.     some_record_type = object
  12.       Procedure WriteItOut;
  13.     end;
  14.  
  15. Procedure some_record_type.WriteItOut;
  16. begin
  17.   writeln( 'Programmer can decide whether this "some_rec_type" is an object or class at compile-time with one easy switch of the value typeofrec!' );
  18.   writeln( 'Right now some_record_type is object' );  // Outputs whether self is object or class
  19. end;
  20.  
  21. var
  22.    some_rec : some_record_type;
  23.  
  24. begin
  25.   New( some_rec );  // Makes some_rec as object/class
  26.   some_rec.WriteItOut;  // Writes message to screen
  27.   Dispose( some_rec );  // Makes some_rec as object/class
  28. end.

If typeofrec equals "class" then the above code precompiles to:

Code: Pascal  [Select][+][-]
  1. Program Ending_Object_Class_War;
  2.  
  3. interface
  4.  
  5. uses
  6.     Classes;
  7.  
  8. implementation
  9.  
  10. type
  11.     some_record_type = class
  12.       Procedure WriteItOut;
  13.     end;
  14.  
  15. Procedure some_record_type.WriteItOut;
  16. begin
  17.   writeln( 'Programmer can decide whether this "some_rec_type" is an object or class at compile-time with one easy switch of the value typeofrec!' );
  18.   writeln( 'Right now some_record_type is class' );  // Outputs whether self is object or class
  19. end;
  20.  
  21. var
  22.    some_rec : some_record_type;
  23.  
  24. begin
  25.   some_rec.Create;  // Makes some_rec as object/class
  26.   some_rec.WriteItOut;  // Writes message to screen
  27.   some_rec.Free;  // Makes some_rec as object/class
  28. end.

The output of the first above is:

Programmer can decide whether this "some_rec_type" is an object or class at compile-time with one easy switch of the value typeofrec!
Right now some_record_type is object


The output of the second above is:

Programmer can decide whether this "some_rec_type" is an object or class at compile-time with one easy switch of the value typeofrec!
Right now some_record_type is class
« Last Edit: March 22, 2019, 01:48:47 pm by IndigoBoy83 »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Proposing 4 New Ideas - #2 Interjections
« Reply #1 on: March 22, 2019, 02:00:46 pm »
This is basically a wooly redefinition of preprocessor, and the standard answer to that is:

sure! Use any external preprocessor you want (but we won't implement it)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Proposing 4 New Ideas - #2 Interjections
« Reply #2 on: March 22, 2019, 08:18:26 pm »
Yep, this is no stronger than a preprocessor. I believe GNU M4 is capable of doing all that you describe already, albeit with different syntax.

 

TinyPortal © 2005-2018