Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Small Command line scripter (like Autocad commands) one line editor

Basically I don't know from where to start, I need to add a line script for my application that is not so complicated, just to execute pre-defined commands, for instance:

command> New Invoice --> create new invoice

command> customer profile --> open customer form where cust id = CustID

command> run End-Of-Day - run the end of day process

command> scr 1020 --> open form id = 1020

How can I start? I have no problem of recommending any third party components (parsers,evaluators,etc..).

whats missing is the basic structure no details, just a theory for implementation.

Thanks, Objectberg

like image 626
Objectsberg Avatar asked Mar 24 '10 16:03

Objectsberg


4 Answers

Maybe you will like this, maybe not. But it sounds actually like you would like to get some basic understanding, too. You might like what I think is a classic first reading on how to build a compiler by Jack Crenshaw. You can find it at this address. It is more than what you are looking for but it's written in Turbo Pascal and the narrative is actually kind of fun to read.

Good luck.

like image 166
jrodenhi Avatar answered Sep 28 '22 02:09

jrodenhi


If it's sufficiently simple (even with optional arguments), something based on TStringList actually works decently. Here's a simple example to get you started:

type
  TCommandRec = record
    Command: string;
    Proc: array(AArgs: TStringList);
  end;

const
  Commands: array(0..4) of TCommandRec = (
    (Command: 'New';      Proc: DoNew),
    (Command: 'Customer'; Proc: DoCustomer),
    (Command: 'Run';      Proc: DoRun),
    (Command: 'Scr';      Proc: DoScr),
    (Command: 'Find';     Proc: DoFind));

procedure RunScript(const AFileName: string);
var
  Script, Args: TStringList;
  i, j: Integer;
begin
  Script := TStringList.Create;
  try
    Script.LoadFromFile(AFileName);
    Args := TStringList.Create;
    try
      Args.Delimiter := ' ';
      for i := 0 to Script.Count - 1 do begin
        Args.DelimitedText := Script[i];
        for j := Low(Commands) to High(Commands) do
          if SameText(Args[0], Commands[j].Command) then begin
            Commands[j].Proc(Args);
            Break;
          end;
      end;
    finally
      Args.Free;
    end;
  finally
    Script.Free;
  end;
end;

procedure DoRun(AArgs: TStringList);
begin
  if SameText(AArgs[1], 'End-of-day') then
    RunEndOfDayProcess
  else if SameText(AArgs[1], 'Hourly') then
    RunHourlyProcess
  else
    raise EInvalidScript.Create;
end;

procedure DoFind(AArgs: TStringList);
var
  FindType: string;
begin
  if (AArgs.Count <> 5) or not SameText(AArgs[2], 'by') then
    raise EInvalidScript.Create;
  if SameText(AArgs[1], 'Cust') then begin
    if SameText(AArgs[3], 'Name') then
      FindCustomer(AArgs[4], '')
    else if SameText(AArgs[3], 'LastName') then
      FindCustomer('', AArgs[4])
  end
  else if SameText(AArgs[1], 'Contact') then begin
    ...
  end
  else
    raise EInvalidScript.Create;
end;

If you have multiple optional arguments (e.g., FIND CUST BY NAME John AND LASTNAME Smith) then, rather than hardcoding the stringlist offsets like I've done above, delete each argument from the stringlist as you process it (or add it to your query). That way, when it's empty you know you're done with the line, and you only need to look at AArgs[0] to see if you recognize the next bit.

like image 38
Zoë Peterson Avatar answered Sep 28 '22 03:09

Zoë Peterson


You could look at tcl. That was its original purpose--to be a tool command language framework which you could embed into another program. Tcl provides a language syntax with variables and control structures (loops etc). You would add tcl commands and functions to access your program's features.

like image 41
Kenster Avatar answered Sep 28 '22 02:09

Kenster


First question: If it's a limited number of canned commands, why not just implement it using menus?

But if you want real scripting, there are plenty of script engines that you can plug into Delphi. Most of them are based on real programming languages, though, which sounds a bit more complicated than what you're looking for.

If you want to design your own simple scripting language, you'll need a bit of knowledge about parser theory. I'd recommend looking around on the GOLD Parser site, which has some theoretical information available and also some tools that will help you set up your own language rules. It has a Delphi implementation available on the site.

like image 26
Mason Wheeler Avatar answered Sep 28 '22 02:09

Mason Wheeler