DerDolch / la-pe

Automatically exported from code.google.com/p/la-pe
0 stars 0 forks source link

Call a procedure directly #26

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
This post is more a newbie question than a bug report...
Thanks for your great job, looks very promising.

I have a question : how to call a procedure with parameters directly?

RunCode(Compiler.Emitter.Code);

runs all the script but I need to call only one declared procedure.
Any solution?

Please provide any additional information below.

Thanks 

Original issue reported on code.google.com by sensomu...@gmail.com on 15 Jun 2013 at 8:53

GoogleCodeExporter commented 9 years ago
You can use the lpffi unit in extensions to create a ExportInclosure(?).

The Simba project uses this if you'd like to look, remember the lpffi unit 
depends on ffi, which depends on the ffi library being present.

Class Helpers, has Natify, and a getByCodePos for the global decls. 
https://github.com/Dgby714/Simba/blob/TMThread_CleanUp/Units/Misc/lpclasshelper.
pas

Also, How Natify is used. 
https://github.com/Dgby714/Simba/blob/TMThread_CleanUp/Units/MMLAddon/lpthread.p
as#L190

or a Sync-like method. 
https://github.com/Dgby714/Simba/blob/TMThread_CleanUp/Units/MMLAddon/lpthread.p
as#L165

Original comment by Dgby...@gmail.com on 18 Jun 2013 at 10:20

GoogleCodeExporter commented 9 years ago
hello,
Thanks for your help and response. An,d sorry for this "but report" which is 
obviously not a bug...

oups, I did not realize that ffi/lpffi was exactly made for that...

But in fact ffi do not compile properly in my environment: I use delphi XE3/ 
FMX building WIN/OSX application.
ffi needs a lot of extra work and also external dylib/dll which makes package 
distribution harder.

It's a very bad news for me since lape was perfect :(

Thanks anyway for your great job.
Let me know if you can find a small workaround because I only need to call a 
particular procedure declared in the script with a simple integer32 parameter.

senso++++

Original comment by sensomu...@gmail.com on 19 Jun 2013 at 8:02

GoogleCodeExporter commented 9 years ago
Take a look at how we use ffi to generate the wrapper, we only use ffi to make 
it dynamic.

You can prob use strait lape if you make it for a specific method.

If you need help with it, I can look into it for you.

Original comment by Dgby...@gmail.com on 19 Jun 2013 at 1:22

GoogleCodeExporter commented 9 years ago
hello,
I really appreciate your interest for my pb and I don't want to abuse of your 
precious time. You did already a great contribution.

ffi is unfortunately outside the scope of my simple mind. I evolve more in DSP 
stuffs, so I'm fluent in FFT not in FFI :)

The things I understand are:

calling 
Compiler.getGlobalVar('my_proc_name');
to get informations about the procedure I want to call (I know by advance how 
many params it has, in my case an integer or eventually no param).

then I have probably to call
RunCode(Code,DoContinue,InitialVarStack,InitialJump);

and put before params in the InitilalStack?
set the proper InitialJump to the Address of the proc?

It's what I imagine, but as you can see my imagination is limited :)
and lots of steps are missing.

Do you have, one again, few minutes to put me in the right way?
thanks a lot.

senso+++

Original comment by sensomu...@gmail.com on 19 Jun 2013 at 3:24

GoogleCodeExporter commented 9 years ago
That is exactly right, InitialJump is just the CodePos, and the InitialVarStack 
you build with your parameters and a result if it is a function.

I was speaking about the lpffi unit, you can see how to build a variable stack 
in it.

Just open the file and search for RunCode.

Original comment by Dgby...@gmail.com on 21 Jun 2013 at 11:26

GoogleCodeExporter commented 9 years ago
hello,
Thanks again.
I think I've got it!

something like the dirty draft bellow (test for a simple integer param):

procedure TForm1.Button1Click(Sender: TObject);
var
  Parser: TLapeTokenizerBase;
  Compiler: TLapeCompiler;
  va : TLapeGlobalVar;
  codepos : TCodePos;
  param : integer;
  VarStack : TByteArray;
  b : integer;

begin

      Parser := TLapeTokenizerString.Create({$IFDEF Lape_Unicode}UTF8Decode(code.Text){$ELSE}code.Text{$IFEND});
      Compiler := TLapeCompiler.Create(Parser);
      InitializePascalScriptBasics(Compiler, [psiTypeAlias]);
      Compiler.addGlobalMethod('procedure trace(s: string);', @MyWrite, Form1);

      try
        if Compiler.Compile() then
          m.Lines.add('Compiling ok')
        else
          m.Lines.add('Error!');
      except
      end;

      b := 0;
      va := Compiler.getGlobalVar('myproc');
      codepos := TCodePos(va.Ptr^);
      param := 7;
      SetLength(VarStack, sizeof(integer));
      Move(param, VarStack[b], sizeof(integer));
      Inc(b, sizeof(integer));
      try
        RunCode(Compiler.Emitter.Code, VarStack, CodePos);
        m.Lines.add('Running done');
      except
      end;
      Compiler.Free;
      parser.Free;
end;

works on WIN32/64 OSX.
Now I have to adapt to my project.

thank a lot for your  help.
senso+++

Original comment by sensomu...@gmail.com on 21 Jun 2013 at 2:18

GoogleCodeExporter commented 9 years ago
Thanks for helping out, Dgby!

Original comment by niels....@gmail.com on 12 Aug 2014 at 2:00