* Scripting support
@ 2005-10-22 13:59 Marco Gerards
2005-10-22 14:46 ` Vladimir Serbinenko
0 siblings, 1 reply; 9+ messages in thread
From: Marco Gerards @ 2005-10-22 13:59 UTC (permalink / raw)
To: grub-devel
Hi,
Last days I have been thinking about scripting support. With my last
patch it should be easy to implement. I hope Vladimir is still
interested in this.
The most important is the general design. I think we shouldn't put
too much in the core and not even in normal mode. This is the same
approach bash has taken. I think the core functionality should be:
- variables (we have that)
- functions
Functions should work *exactly* like normal GRUB commands. In
that case we can easily mix GRUB commands and functions.
- Return values
All commands should be able to return a value. That's also what
bash has. This value can be stored in a variable or simply
returned, I am not too sure about that. Just check what bash
does.
- Conditional statements like if and case
- loops: until, while and for
Whenever a command line should be executed or when a script file is
executed, it's the same. The block of code is just parsed and
executed by a function (the parser, I guess :)).
It's important to see that GRUB does not do anything like
calculations. All this can be moved into a command. When making a
bash script you have the same, there is the expr command. So we have
to keep the core functionality minimal and should offer the commands
in command/ like we do now.
First the lexer. I think it should work like this:
normal/parser.c should contain the lexer. The prototypes etc. can
just be added to include/grub/parser.h.
There are just a few tokens we have to recognize. Think about stuff
like a string of text, if, elif, case, ;, [], etc.
The parser can be quite simple. It has to support all kinds of loops,
etc. I am not sure how to deal with that. perhaps we have to feed
the block within a for loop (for example) to the parser until the for
loop exits. Another possibility is creating some kind of P-code and
parse that later on. I wonder what the best approach is.
For the parser we should use bison, I think. Writing a handwritten
parser is acceptable if some standard approach is taken and it's
really really clean and well documented.
Any idea is welcome. I hope we can discuss the implementation in
detail so we can have scripting support soon.
Thanks,
Marco
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Scripting support
2005-10-22 13:59 Scripting support Marco Gerards
@ 2005-10-22 14:46 ` Vladimir Serbinenko
2005-10-22 15:08 ` Marco Gerards
2005-10-28 3:04 ` Yoshinori K. Okuji
0 siblings, 2 replies; 9+ messages in thread
From: Vladimir Serbinenko @ 2005-10-22 14:46 UTC (permalink / raw)
To: The development of GRUB 2
Marco Gerards wrote:
>Hi,
>
>Last days I have been thinking about scripting support. With my last
>patch it should be easy to implement. I hope Vladimir is still
>interested in this.
>
>
Yes. Exactly now I'm on holiday so I have a lot of time. And also I have
some ideas for some new GRUB features but theese features aren't useful
without scripting so I'm interested more than ever.
>The most important is the general design. I think we shouldn't put
>too much in the core and not even in normal mode. This is the same
>approach bash has taken. I think the core functionality should be:
>
>- variables (we have that)
>- functions
> Functions should work *exactly* like normal GRUB commands. In
> that case we can easily mix GRUB commands and functions.
>
>
In bash when you define a function it appears under environment
variables. IMHO it's useless to store completely the source code as an
environment variables. I propose that the functions will be preparsed
(converted to internal format ready for execution) because it will
gretelya simplify lexer and parser
>- Return values
> All commands should be able to return a value. That's also what
> bash has. This value can be stored in a variable or simply
> returned, I am not too sure about that. Just check what bash
> does.
>
>
Could it be merged with error variable. It's what bash does
>- Conditional statements like if and case
>- loops: until, while and for
>
>
>
I propose the following argorithm. Bison parser transforms the text-form
to internal form of a linked list of commands with some special commands
like jump if last value was true, ... . Think about assembler. Then it's
executed by simple engine that works like CPU: it takes one command from
a linked list. Executes it and changes the pointer so it points to the
next command. A command is a structure containing:
variable showing it's type (normal command, jump, loop, end of loop,
...)
union of data necessary for necessary commands
pointer to next command.
I made a simple example I posted as preview version of scripting engine
and I also posted on this list simple design doc.
Any ideas are welcome.
Vladimir 'phcoder'
Serbinenko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Scripting support
2005-10-22 14:46 ` Vladimir Serbinenko
@ 2005-10-22 15:08 ` Marco Gerards
2005-10-22 15:37 ` Vladimir Serbinenko
2005-10-28 3:04 ` Yoshinori K. Okuji
1 sibling, 1 reply; 9+ messages in thread
From: Marco Gerards @ 2005-10-22 15:08 UTC (permalink / raw)
To: The development of GRUB 2
Vladimir Serbinenko <phcoder@gmail.com> writes:
Hi Vladimir,
>>Last days I have been thinking about scripting support. With my last
>>patch it should be easy to implement. I hope Vladimir is still
>>interested in this.
>>
>>
> Yes. Exactly now I'm on holiday so I have a lot of time. And also I
> have some ideas for some new GRUB features but theese features aren't
> useful without scripting so I'm interested more than ever.
Nice.
>>The most important is the general design. I think we shouldn't put
>>too much in the core and not even in normal mode. This is the same
>>approach bash has taken. I think the core functionality should be:
>>
>>- variables (we have that)
>>- functions
>> Functions should work *exactly* like normal GRUB commands. In
>> that case we can easily mix GRUB commands and functions.
>>
>>
> In bash when you define a function it appears under environment
> variables. IMHO it's useless to store completely the source code as an
> environment variables. I propose that the functions will be preparsed
> (converted to internal format ready for execution) because it will
> gretelya simplify lexer and parser
Right. We should discuss the internal format on the list, I think.
>>- Return values
>> All commands should be able to return a value. That's also what
>> bash has. This value can be stored in a variable or simply
>> returned, I am not too sure about that. Just check what bash
>> does.
>>
>>
> Could it be merged with error variable. It's what bash does
Ok.
>>- Conditional statements like if and case
>>- loops: until, while and for
>>
>>
>>
> I propose the following argorithm. Bison parser transforms the
> text-form to internal form of a linked list of commands with some
> special commands like jump if last value was true, ... . Think about
> assembler. Then it's executed by simple engine that works like CPU: it
> takes one command from a linked list. Executes it and changes the
> pointer so it points to the next command. A command is a structure
> containing:
> variable showing it's type (normal command, jump, loop, end of
> loop, ...)
> union of data necessary for necessary commands
> pointer to next command.
Right. And this can be kept quite simple. The commands itself are
just a string of text. The loops just check a variable, no? It can
be something like:
for foo in 1 2 3
do
echo $i
done
That can be translated into some kind of pseudo language:
1: list = 1 2 3
2: read i, list
3: echo $i
4: check list
5: je 2
I know it's stupid and kind of silly like this. But we have to define
a language. It's important to discuss this on the list, IMO.
> I made a simple example I posted as preview version of scripting
> engine and I also posted on this list simple design doc.
> Any ideas are welcome.
I think I gave you some ideas. ;)
Which mail are you talking about (subject and date)? I must have
missed a few the last months. :-(
--
Marco
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Scripting support
2005-10-22 15:08 ` Marco Gerards
@ 2005-10-22 15:37 ` Vladimir Serbinenko
2005-10-22 15:47 ` Marco Gerards
0 siblings, 1 reply; 9+ messages in thread
From: Vladimir Serbinenko @ 2005-10-22 15:37 UTC (permalink / raw)
To: The development of GRUB 2
Hello
>
>
>
>>In bash when you define a function it appears under environment
>>variables. IMHO it's useless to store completely the source code as an
>>environment variables. I propose that the functions will be preparsed
>>(converted to internal format ready for execution) because it will
>>gretelya simplify lexer and parser
>>
>>
>
>Right. We should discuss the internal format on the list, I think.
>
>
>
>Right. And this can be kept quite simple. The commands itself are
>just a string of text. The loops just check a variable, no? It can
>be something like:
>
>for foo in 1 2 3
> do
> echo $i
> done
>
>That can be translated into some kind of pseudo language:
>
>1: list = 1 2 3
>2: read i, list
>3: echo $i
>4: check list
>5: je 2
>
>I know it's stupid and kind of silly like this. But we have to define
>a language. It's important to discuss this on the list, IMO.
>
>
>
I thought about (a):
1: command=forin variable=i list=1 2 3 end=NULL /* it will be 4 if
script continues*/
2: echo $i
3: jump 1
Or (b):
1:splitpush 1 2 3
2:pop list
3:read i, list
4:push list
5:echo $i
6:pop list
7:check list
8:push list
9:je 2
10:pop list
The question is how many commands to make: a lot (like in a where nearly
every internal command corresponds to a scripting command) or make so
few commands as possible. I wonder which approach is better (it's
question about bugs and readibility, of course, not about speed)
>Which mail are you talking about (subject and date)? I must have
>missed a few the last months. :-(
>
>
Re: [Patch] Scripting engine 25.09.2005
[Patch] Scripting engine 24.08.2005
It's just demonstration of some ideas. Now I think with new splitter it
would be better to keep arglist unparsed. In this patch it was that if
we have
echo 1 2 3\;\$ ab$i;
lexer returns (schematically)
STRING(echo) STRING(1) STRING(2) STRING (3;$) STRING(abVAR(i)) SEMICOLON
now I would do that it returns:
STRING(echo 1 2 3\;\$ ab$i) SEMICOLON
Vladimir 'phcoder' Serbinenko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Scripting support
2005-10-22 15:37 ` Vladimir Serbinenko
@ 2005-10-22 15:47 ` Marco Gerards
2005-10-22 16:03 ` Vladimir Serbinenko
2005-10-22 16:33 ` Marco Gerards
0 siblings, 2 replies; 9+ messages in thread
From: Marco Gerards @ 2005-10-22 15:47 UTC (permalink / raw)
To: The development of GRUB 2
Vladimir Serbinenko <phcoder@gmail.com> writes:
>>That can be translated into some kind of pseudo language:
>>
>>1: list = 1 2 3
>>2: read i, list
>>3: echo $i
>>4: check list
>>5: je 2
>>
>>I know it's stupid and kind of silly like this. But we have to define
>>a language. It's important to discuss this on the list, IMO.
>>
>>
>>
> I thought about (a):
Right. It's also possible.
> The question is how many commands to make: a lot (like in a where
> nearly every internal command corresponds to a scripting command) or
> make so few commands as possible. I wonder which approach is better
> (it's question about bugs and readibility, of course, not about speed)
I think we first have to determine:
1) Which commands should be supported.
2) The smallest subset of commands that should be generated.
Did you have a look at how bash does this? Perhaps it even has a
completely different approach...
>>Which mail are you talking about (subject and date)? I must have
>>missed a few the last months. :-(
>>
>>
> Re: [Patch] Scripting engine 25.09.2005
> [Patch] Scripting engine 24.08.2005
> It's just demonstration of some ideas. Now I think with new splitter
> it would be better to keep arglist unparsed. In this patch it was that
> if we have
> echo 1 2 3\;\$ ab$i;
> lexer returns (schematically)
> STRING(echo) STRING(1) STRING(2) STRING (3;$) STRING(abVAR(i)) SEMICOLON
> now I would do that it returns:
> STRING(echo 1 2 3\;\$ ab$i) SEMICOLON
Perhaps the best is to make a list of tokens we need to support. With
such list we can determine how to detect them.
Thanks,
Marco
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Scripting support
2005-10-22 15:47 ` Marco Gerards
@ 2005-10-22 16:03 ` Vladimir Serbinenko
2005-10-22 16:42 ` Marco Gerards
2005-10-22 16:33 ` Marco Gerards
1 sibling, 1 reply; 9+ messages in thread
From: Vladimir Serbinenko @ 2005-10-22 16:03 UTC (permalink / raw)
To: The development of GRUB 2
Marco Gerards wrote:
>Vladimir Serbinenko <phcoder@gmail.com> writes:
>
>
>
>
>I think we first have to determine:
>
>1) Which commands should be supported.
>
>
What about
&& || ! case do done elif else esac fi for function if in then until
while { } [[ ]]
in scripting engine. I think that time is completely useless. What do
you think about select?
>2) The smallest subset of commands that should be generated.
>
>
>
I think
jmp
je/jne
invert (not for last return)
exec
regexp (check if string matches regexp)
push
pop
getelem (get element from list)
should be enough
External commands would be eval and [[
functions can be stored directly by parser
>
>Perhaps the best is to make a list of tokens we need to support. With
>such list we can determine how to detect them.
>
>
I think just comparing (after \ one character is not compared) might be
enough.
; newline ;; && || ! case do done elif else esac fi for function if in
then until while { } [[ ]]
>Thanks,
>Marco
>
>
>
>
Vladimir
'phcoder' Serbinenko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Scripting support
2005-10-22 15:47 ` Marco Gerards
2005-10-22 16:03 ` Vladimir Serbinenko
@ 2005-10-22 16:33 ` Marco Gerards
1 sibling, 0 replies; 9+ messages in thread
From: Marco Gerards @ 2005-10-22 16:33 UTC (permalink / raw)
To: The development of GRUB 2
Marco Gerards <metgerards@student.han.nl> writes:
> I think we first have to determine:
>
> 1) Which commands should be supported.
> 2) The smallest subset of commands that should be generated.
>
> Did you have a look at how bash does this? Perhaps it even has a
> completely different approach...
I just had a look at bash. It was a quick look, so I might be
mistaken, but I think it works like this:
First bash parses the script (in parse.y). It uses a make_*_command
to generate stuff like if, for, case, etc (make_*command is in
make_cmd.c). After that it executes the commands (in execute_cmd.c).
We could parse this script:
for i in 1 2 3
do
echo foo
echo bar
echo $i
done
echo done!
into something like:
struct command
{
command_type_t type;
};
struct for_command
{
struct command command;
list_t list;
struct cmdlist_command *cmds;
}
/* A simple GRUB command. */
struct simple_command
{
struct command command;
char *command;
};
/* Lines of commands. */
struct cmdlist_command
{
struct command command;
struct command **cmdlist;
};
struct cmdlist_command script
{
grub_cmdtype_cmdlist,
{
{
cmd_type_for,
{1, 2, 3},
{
grub_cmdtype_cmdlist,
{
{ grub_cmdtype_simple, "echo foo" },
{ grub_cmdtype_simple, "echo bar" },
{ grub_cmdtype_simple, "echo $i" }
}
}
},
{
grub_cmdtype_simple, " echo done!"
}
}
This is of course not the code what is generated. And when
implementing it, you would use pointers. But logically it is nested
that way. After that you can execute it like this:
execute_cmd (struct command *cmd)
{
switch (cmd->type)
{
case grub_cmdtype_if:
{
struct if_command *cmd_if = (struct if_command *) cmd;
execute_if_cmd (cmd_if);
}
case grub_cmdtype_for:
...
}
}
This is quite ugly code, but I hope you get the idea. :)
Vladimir, if you want I could implement the framework like I have in
mind. It is not that much work. The hard part is "filling in" the
framework so you get scripting support. Please tell me what you
think, or we could talk about it on IRC.
Thanks,
Marco
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Scripting support
2005-10-22 16:03 ` Vladimir Serbinenko
@ 2005-10-22 16:42 ` Marco Gerards
0 siblings, 0 replies; 9+ messages in thread
From: Marco Gerards @ 2005-10-22 16:42 UTC (permalink / raw)
To: The development of GRUB 2
Vladimir Serbinenko <phcoder@gmail.com> writes:
>>I think we first have to determine:
>>
>>1) Which commands should be supported.
>>
>>
> What about && || ! case do done elif else esac fi for function if in
> then until while { } [[ ]]
This sounds fine to me. Although I don't remember !, { } and [[ ]]
anymore.
> in scripting engine. I think that time is completely useless. What do
> you think about select?
I am not sure about select.
What is "time" you are talking about? If you are talking about the
command time which measures the running time, it is just a command.
If we want it, we can easily implement it as a GRUB command.
>>2) The smallest subset of commands that should be generated.
>>
> I think
If we take the approach I described in my other email, we don't need
this. So I wait for commenting about this.
>>Perhaps the best is to make a list of tokens we need to support. With
>>such list we can determine how to detect them.
>>
>>
> I think just comparing (after \ one character is not compared) might
> be enough.
The \ is already handled by the state machine, when I commit it. So
it is not something you have to worry about. :-)
> ; newline ;; && || ! case do done elif else esac fi for function if in
> then until while { } [[ ]]
Right. And how about menu entries? What was the last thing we agreed
about?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Scripting support
2005-10-22 14:46 ` Vladimir Serbinenko
2005-10-22 15:08 ` Marco Gerards
@ 2005-10-28 3:04 ` Yoshinori K. Okuji
1 sibling, 0 replies; 9+ messages in thread
From: Yoshinori K. Okuji @ 2005-10-28 3:04 UTC (permalink / raw)
To: The development of GRUB 2
On Saturday 22 October 2005 04:46 pm, Vladimir Serbinenko wrote:
> I propose the following argorithm. Bison parser transforms the text-form
> to internal form of a linked list of commands with some special commands
> like jump if last value was true, ... . Think about assembler. Then it's
> executed by simple engine that works like CPU: it takes one command from
> a linked list. Executes it and changes the pointer so it points to the
> next command. A command is a structure containing:
> variable showing it's type (normal command, jump, loop, end of loop,
> ...)
> union of data necessary for necessary commands
> pointer to next command.
Ahghh. Please avoid making yet another language. Since the language constructs
in shell is so few, I don't see much benefit from such a translation.
Okuji
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-10-28 3:04 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-22 13:59 Scripting support Marco Gerards
2005-10-22 14:46 ` Vladimir Serbinenko
2005-10-22 15:08 ` Marco Gerards
2005-10-22 15:37 ` Vladimir Serbinenko
2005-10-22 15:47 ` Marco Gerards
2005-10-22 16:03 ` Vladimir Serbinenko
2005-10-22 16:42 ` Marco Gerards
2005-10-22 16:33 ` Marco Gerards
2005-10-28 3:04 ` Yoshinori K. Okuji
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.