FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

pragma(plugin...)

 
Post new topic   Reply to topic     Forum Index -> Build
View previous topic :: View next topic  
Author Message
sergiodi45



Joined: 13 Feb 2005
Posts: 6

PostPosted: Sun Mar 06, 2005 3:01 pm    Post subject: pragma(plugin...) Reply with quote

This follows the discussion on the D forum.

I think it could be a good idea to start implementing this with Build.

This is the construct:

pragma (plugin, name,
... anything...
)

When a plugin pragma is found:
- Copy the "anything" code to the stdin of the "name" plugin
- get the stdout of the plugin witch must be D code and paste it in the source file

Then, compile the resulting file.

Plugins which should be very usefull:

- One sort of yacc, or a DGrammar adaptation

pragma(plugin, grammar,
body: "START" code "STOP";
code: expression expression_list;
expression: string(a) | integer(b) {
D code using variables a and b
}
etc..
)

- A ressource plugin that convert binary file into an array of char[]

pragma(plugin, ressource,
image = ../image.png
data = data.dat
)

- An "ASCII" writer which add writefln(" and ") in the beginning end ending of each line

pragma(plugin, ascii,

Usage: build options

Options:
- P : Do this
- O : Do that

)


Admit it's cleaner !

- An inline regexp plugin maybe
- And all we like....
Back to top
View user's profile Send private message AIM Address MSN Messenger
Derek Parnell



Joined: 22 Apr 2004
Posts: 408
Location: Melbourne, Australia

PostPosted: Sun Mar 06, 2005 5:00 pm    Post subject: Reply with quote

I sort of like the idea too, but there are some issues which need careful thinking about first.

The main is, how do I get the resulting output of the plugins to DMD?

Build is reading one or more source files, if it finds a plugin request, it calls the plugin and gets some new source text. Where does build store that new text? It can't store it in the original source file because it would update somebody's code. I can't put it in to an file that is imported, because imports are not allowed in all the contexts that the pragma is allowed it, and how would I tell DMD to import it anyweay seeing I can't update the orginal source file. So I'd probably have to copy the original source file, merge in the new text, to a new source file which is in turn given to DMD to compile. But if I do that, we now have problems with module names. If the original source didn't have a module name, it takes the name of the source file as its module name, but with the plugin source, I've now got a different source file name. Okay, so I could insert a module statement to fix the module name. But now we could have problems with other files trying to import the plugged-in file - it has a different name to what was expected. And of course, we are talking about multiple original source files on the same DMD call.

One of the basic reasons for build is to detect dependancies between source files and only compile the ones that require recompiling. So how do I detect updated files used by a plugin? I mean, if you update one of these, but do not update the D source that is dependant on it, how would build know to recompile it?

Then there is the issue of ~ does build rescan the text supplied by the plugin? This could lead to further temporary files being created.

How, if at all, can we pass context information to different calls to the same plugin, or do we leave this entirely up to the plugin to manage.

The text supplied by the plugin will change the line numbers relative to the original source file. This means that error messages coming from DMD will reference the 'wrong' line number. Build could put in #LINE statements, but this becomes confusing if there are errors inside the plugin supplied text.

And I'm sure there are other problems about this I haven't thought of yet.
_________________
--
Derek
skype name: derek.j.parnell
Back to top
View user's profile Send private message
sergiodi45



Joined: 13 Feb 2005
Posts: 6

PostPosted: Mon Mar 07, 2005 9:55 am    Post subject: Reply with quote

Well, this is why I though it could have been more easier to manage this inside DMD itself...

However :

1) We must admit that the code supplied by the plugin has NO error.
If there's something wrong with the "embedded" code, the plugin must say that there's a problem and don't supply any erroreneous D code.

2) No recursive plugin calls: D code generated by a plugin must NOT have any other pragma plugin statement.

3) Plugin code must NOT import any other modules.

4) If BUILD find one or more pragma plugin in the file source.d, it should:

- Create a TMP directory, if it's not done yet

- Move source.d to TMP

- Tell the compiler about the LINES changes

- Call the plugin(s) so as to create a new source.d in the main folder.
Meanwhile: build could replace the folowings:
__FILE__, __DATE__, __LINE__ by their values in the new sources.d

- Compile

When all is finished:

Move the original files in TMP back in the main folder, replacing the plugin version.

Delete the TMP folder.

Finally the user don't see nothing.
Except if a switch is anabled in the build command line asking it to show him the resulting code somewhere.

(so the user can, but shouldn't, see the temporary code)

Is build using timestamps to know whether a file must be recompiled ?
I suggest using MD5 checksums instead.
Back to top
View user's profile Send private message AIM Address MSN Messenger
Derek Parnell



Joined: 22 Apr 2004
Posts: 408
Location: Melbourne, Australia

PostPosted: Tue Mar 08, 2005 1:56 am    Post subject: Reply with quote

sergiodi45 wrote:
Well, this is why I though it could have been more easier to manage this inside DMD itself...

Agreed.
sergiodi45 wrote:
However :

1) We must admit that the code supplied by the plugin has NO error.
If there's something wrong with the "embedded" code, the plugin must say that there's a problem and don't supply any erroreneous D code.
Nice, but we don't live in a perfect world.

sergiodi45 wrote:
2) No recursive plugin calls: D code generated by a plugin must NOT have any other pragma plugin statement.
But people will try anyway.

sergiodi45 wrote:
3) Plugin code must NOT import any other modules.
But they will want to.
sergiodi45 wrote:
4) If BUILD find one or more pragma plugin in the file source.d, it should:

- Create a TMP directory, if it's not done yet

- Move source.d to TMP

- Tell the compiler about the LINES changes

- Call the plugin(s) so as to create a new source.d in the main folder.
Meanwhile: build could replace the folowings:
__FILE__, __DATE__, __LINE__ by their values in the new sources.d

- Compile

When all is finished:

Move the original files in TMP back in the main folder, replacing the plugin version.

Delete the TMP folder.

And it has to most of this even if it doesn't find one, just in case.

sergiodi45 wrote:
Finally the user don't see nothing.
Except if a switch is anabled in the build command line asking it to show him the resulting code somewhere.

(so the user can, but shouldn't, see the temporary code)
Yes, that sounds good.

sergiodi45 wrote:
Is build using timestamps to know whether a file must be recompiled ?
I suggest using MD5 checksums instead.

And what do I comapre the checksum to?
_________________
--
Derek
skype name: derek.j.parnell
Back to top
View user's profile Send private message
sergiodi45



Joined: 13 Feb 2005
Posts: 6

PostPosted: Tue Mar 08, 2005 11:09 am    Post subject: Reply with quote

Okay.

Build could quickly scan the plugin's output for "import" and "pragma".
And just stop on an error if it finds one.

Timestamps won't work with this system because when you'll move/delete files it's all get changed.
Just create a checksum database file, a hidden file like ".builddb" in witch you stock sets of Filename/Checksum ?

I don't know... it would be really better if the compiler could do that.
But obviously nobody seems to react to my proposition ...?

If anybody has any idea, please talk, this is the place to debate about it.
Back to top
View user's profile Send private message AIM Address MSN Messenger
Derek Parnell



Joined: 22 Apr 2004
Posts: 408
Location: Melbourne, Australia

PostPosted: Wed Mar 09, 2005 3:13 am    Post subject: Reply with quote

sergiodi45 wrote:
Okay.

Build could quickly scan the plugin's output for "import" and "pragma".
And just stop on an error if it finds one.

Timestamps won't work with this system because when you'll move/delete files it's all get changed.
Just create a checksum database file, a hidden file like ".builddb" in witch you stock sets of Filename/Checksum ?

I don't know... it would be really better if the compiler could do that.
But obviously nobody seems to react to my proposition ...?

If anybody has any idea, please talk, this is the place to debate about it.


This is starting to become a little 'out of scope' for the tool. It adds a level of complexity that can only cause more bugs in it than is worth it for now. I'll keep it in the TODO list, but I'm not inclined to implement yet. Maybe if there is much more demand for it.
_________________
--
Derek
skype name: derek.j.parnell
Back to top
View user's profile Send private message
misterpib



Joined: 14 Jan 2005
Posts: 7
Location: Corvallis, OR

PostPosted: Wed Apr 06, 2005 6:48 pm    Post subject: Reply with quote

Derek Parnell wrote:
I sort of like the idea too, but there are some issues which need careful thinking about first.

The main is, how do I get the resulting output of the plugins to DMD?


A Simple Solution:

Well, for files that have this "meta-d" in them, give them the extention .md rather than .d

Then when build is building your program, and it's looking foo.d, but that doesn't exist and foo.md does (or if foo.d and foo.md both exist, but foo.md has a more recent timestamp), then build scans the file, fills in any plugin sections, and outputs the resulting file into foo.d

It's a perfectly feasible idea.

Basically inspired by the way Javacc (and other compiler compilers) work. Start with a file with one extention, convert it to another. Javacc even takes this a step further by providing another program that will take a meta-grammar file, and generate your grammar file for you so the generated .java program will build your source tree for you.
Multiple layers Razz
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Derek Parnell



Joined: 22 Apr 2004
Posts: 408
Location: Melbourne, Australia

PostPosted: Wed Apr 06, 2005 7:02 pm    Post subject: Reply with quote

misterpib wrote:
Derek Parnell wrote:
I sort of like the idea too, but there are some issues which need careful thinking about first.

The main is, how do I get the resulting output of the plugins to DMD?


A Simple Solution:

Well, for files that have this "meta-d" in them, give them the extention .md rather than .d

Then when build is building your program, and it's looking foo.d, but that doesn't exist and foo.md does (or if foo.d and foo.md both exist, but foo.md has a more recent timestamp), then build scans the file, fills in any plugin sections, and outputs the resulting file into foo.d

It's a perfectly feasible idea.

It sure is. Cool

I also came up with this type of 'solution' too. I expect that this will be how it's done. I'm actually converting a general purpose macro processor that I wrote into D, and plan to use that to transform .md files into .d files.

I'm not starting to implement this idea until the version 2 series of Build.
_________________
--
Derek
skype name: derek.j.parnell
Back to top
View user's profile Send private message
sergiodi45



Joined: 13 Feb 2005
Posts: 6

PostPosted: Sat Apr 09, 2005 12:36 pm    Post subject: Reply with quote

Please don't make another C preprocessor clone....
Back to top
View user's profile Send private message AIM Address MSN Messenger
misterpib



Joined: 14 Jan 2005
Posts: 7
Location: Corvallis, OR

PostPosted: Tue May 03, 2005 11:17 am    Post subject: Reply with quote

I guess I should come on these forums more recently.

I completely forgot that I had posted here Razz

good to hear that you're planning on implementing it.
I hope to have some input into it as it comes along Smile

now all we need is a complete parser for (meta-)D that will read in a file and put it in a structure we can easily go through and modify to fit our needs. This could already exist, I dunno...
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
pragma



Joined: 28 May 2004
Posts: 607
Location: Washington, DC

PostPosted: Tue May 03, 2005 12:03 pm    Post subject: Late to the party. Reply with quote

I couldn't help but notice the similarities between DSP and this feature. I'd like to share how I tackled some of these issues, and how it may work well for build as well.

Given the statement:
Code:
pragma(plugin,name){ /* code */ }


Emit a file temp file containing:
Code:
import build.plugin;

pragma(dep,"/original/source/file.d");

export(C) extern(Windows) void doPlugin(/* parameters */){
try{
#line X "/original/source/file.d"
     /* exact plugin code */

#line Y "/this/source/file.d"
}
catch(Exception e){
    /* handle exception */
}
catch(Object o){
    /* handle exception */
}
}


... and then compile it into a dll, and run the exported handle when the plugin is called.

There's a good deal packed into that example. Allow me to break it down.

- "pragma(dep,filename)" - can be added to build to manually insert a dependency between this file and another one. It is used here to document the dependency between the plugin temporary file and it's source where the original pragma() can be found. This way, build can be smart and rebuild the plugin if the parent source was updated.

- "build.plugin" - would be a source file that includes all the goodies that make a plugin work. WinMain, text processing functions, additional exports, can all go here.

- "#line X" - Having used the #line pragmas myself, I can say they work great, and only help debugging code. The developer is given a line number in the correct file, and they're none the wiser that its being compled someplace else. Simply provide the line number of the first line of code for the plugin in 'X'.

- "#line Y" - Like before, tell the compiler that we're back in this file. You won't likely have any trouble beyond this point as it's boilerplate code. However, it helps for diagnostics to point at the right line number. Smile

- "try...catch" - D fails horribly if you throw across the dll-process boundary. *Always* catch at the handler level and do something smart with it like return it to the caller or emit a message there.

The temporary filename should include a non-namespace character like '~' to avoid collisions with valid D source. This way, the plugin temp files can be emitted side-by-side with the parent source.

Code:
myfile.d - contains pragma(plugin)
myfile~foobar.d - temporary for plugin 'foobar'
myfile~foobar.obj
myfile~foobar.def
myflie~foobar.dll - and so on...


As Derek mentioned, compilation is tricky, becuase of the potential for recursive plugins. Why not provide build with a "-noplugin" switch to unconditionally turn-off plugin evaluation? Then build can launch itself to compile a plugin.

Code:
build -noplugin myfile~foobar.d

_________________
-- !Eric.t.Anderton at gmail
Back to top
View user's profile Send private message Yahoo Messenger
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Build All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group