1. 2 Pass Binder

Some thoughts on the two-pass binder.

I've been working on auto-generating the GTK wrappers; the resulting file is
over 500K. Part of the size comes from obscenely-large function names, like
gtk_accel_group_lock_entry. Shrouding the file should take care of a lot of
that. But it also links to all the GTK routines, of which the user is likely
to only use a small percentage. It would be nice if the two-pass binder got
rid of the overhead, but it might have problems, because I declare wrappers
like this:

    constant foo_ = define_c_routine( gtc, "foo", {} )
    global procedure foo()
      c_proc( foo_, {} )
    end procedure

I would imagine that the first pass would get rid of the routine foo(), but
leave the constant foo_.

Since my libraries tend to use routine_id heavily, the two-pass binder
wouldn't be usable anyway, right?

I guess I can always rewrite my binder routine.

-- David Cuny

new topic     » topic index » view message » categorize

2. Re: 2 Pass Binder

David Cuny writes:
>    constant foo_ = define_c_routine( gtc, "foo", {} )
>    global procedure foo()
>      c_proc( foo_, {} )
>    end procedure
> I would imagine that the first pass would get rid of the
> routine foo(), but leave the constant foo_.
> Since my libraries tend to use routine_id heavily, the
> two-pass binder wouldn't be usable anyway, right?

Hmmm... I guess the 2-pass binder will have to be
more sophisticated than I thought. At the end of the
first pass it will have to traverse a large data structure
that shows which symbols are needed by which other
symbols. It will do a kind of "transitive closure" operation
to garbage-collect the unused symbols. Any symbol that
is needed will be marked, then any symbol needed by
*that* symbol will be marked... On the second pass
any unmarked symbols will be skipped as
code is being written out to the .exe.

Constant strings inside routine_id("...") calls will be
examined too, and it will be assumed that a symbol
is needed if it might be the target of a routine_id() call.
If you have routine_id(expression) where the binder
can't tell which routine(s) you are referencing, it will
have to mark all possible routines (earlier in the source,
and visible).

Regards,
     Rob Craig
     Rapid Deployment Software
     http://members.aol.com/FilesEu/

new topic     » goto parent     » topic index » view message » categorize

3. Re: 2 Pass Binder

Robert Craig replied:

> Hmmm... I guess the 2-pass binder will
> have to be more sophisticated than I thought.

If you included marking references in routine_id, you could simply shround
the program multiple times. Each pass would create dangling symbols, until
the symbol set became stable. The calls to routine_id were the only
complexity I could think of. It lacks finesse, but it may be less
error-prone than trying to maintain the links in data structures.

-- David Cuny

new topic     » goto parent     » topic index » view message » categorize

4. Re: 2 Pass Binder

Rob:
    Why not on the FIRST PASS of bind, scan the source and build a symbol
    table that contains
    1: any time a constant or variable is used
    2: any time a function is used
    3: any time a procedure is used
    The final result is symbol table containing a list of each item used.
    The next pass you do the real bind and anything that is not in the
    the symbol table is thrown away.
Bernie

new topic     » goto parent     » topic index » view message » categorize

5. Re: 2 Pass Binder

Maybe this is totally off-track, but what if:

>pseudo-code follows:<
...call to r_id[1..200] = routine_id() 200 times

for i = 1 to 200 do
    call_function/procedure(i)
end for

I know this is sloppy/not particularly useful, but such code would not make
specific reference to any particular routine_id() value.

--noah

Bernie Ryan wrote:

> Rob:
>     Why not on the FIRST PASS of bind, scan the source and build a symbol
>     table that contains
>     1: any time a constant or variable is used
>     2: any time a function is used
>     3: any time a procedure is used
>     The final result is symbol table containing a list of each item used.
>     The next pass you do the real bind and anything that is not in the
>     the symbol table is thrown away.
> Bernie

new topic     » goto parent     » topic index » view message » categorize

6. Re: 2 Pass Binder

Bernie Ryan wrote:

>Rob:
>    Why not on the FIRST PASS of bind, scan the source and build a symbol
>    table that contains
>    1: any time a constant or variable is used
>    2: any time a function is used
>    3: any time a procedure is used
>    The final result is symbol table containing a list of each item used.
>    The next pass you do the real bind and anything that is not in the
>    the symbol table is thrown away.

Because that wouldn't work with routine_id(). If you have several
routines that are ONLY accessed via call_func/proc, there's a
good chance you'll throw away necessary code.

Sure, if routine_id is always given a literal as a parameter, no
problem; but when you have a any sort of variable passed in, this
method won't work.


Rod

new topic     » goto parent     » topic index » view message » categorize

7. Re: 2 Pass Binder

On Tue, 17 Aug 1999 13:46:51 -0500, noah smith
<option1 at OPTIONINTERACTIVE.COM> wrote:

>for i = 1 to 200 do
>    call_function/procedure(i)
>end for
>

You do not understanding what I am talking about !
It does not matter how MANY times the function is called ONLY that
the function was used.
The fact that call_function/procedure(i) was used is entered in the
table .

new topic     » goto parent     » topic index » view message » categorize

8. Re: 2 Pass Binder

Hmmm I thought the question was address to ROB

new topic     » goto parent     » topic index » view message » categorize

9. Re: 2 Pass Binder

Bernie Ryan wrote:

>Hmmm I thought the question was address to ROB

????

So then you chose to send it to the list instead of to Rob
privately because....?


Rod

new topic     » goto parent     » topic index » view message » categorize

10. Re: 2 Pass Binder

Bernie Ryan wrote:

>Hmmm I thought the question was address to ROB

Then send it to him, not to the list.


   Gabriel Boehme

new topic     » goto parent     » topic index » view message » categorize

11. Re: 2 Pass Binder

Bernie Ryan writes:
>  Why not on the FIRST PASS of bind, scan the source and
> build a symbol table ...

You are just repeating what the rest of us have
been discussing all along.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

12. Re: 2 Pass Binder

-------Phoenix-Boundary-07081998-
Content-type: text/plain; charset=ISO-8859-1
Content-transfer-encoding: Quoted-printable

(note: two versions of this mail might show up; problems
sending from work, so I tried again from home)
Does a 2 pass binding process offer the possibility of
forward referencing without routine_id()=3F

I don't know squat about interpreters/compilers; I just
wondered if the symbol collection you'll be doing to
remove deadwood could be put to that use as well.

On second thought, that would cause some divisiveness
between code intended for registered/nonregistered
use, wouldn't it=3F

BTW, congrats on the new site, Robert!

Craig
bytebrain at mindspring.com
---------------------------------------
Save the whales. Collect the whole set.

-------Phoenix-Boundary-07081998---

new topic     » goto parent     » topic index » view message » categorize

13. Re: 2 Pass Binder

On Tue, 17 Aug 1999 20:39:24 -0400, Robert Craig <rds at ATTCANADA.NET> wrote:

>You are just repeating what the rest of us have
>been discussing all along.

   I guess am just dumb.
   It seems like you are making the problem more complicated than it is.
   To solve the routine id problem just scan from the bottom up.
Bernie

new topic     » goto parent     » topic index » view message » categorize

14. Re: 2 Pass Binder

Craig writes:
> Does a 2 pass binding process offer the possibility of
> forward referencing without routine_id()?
> On second thought, that would cause some divisiveness
> between code intended for registered/nonregistered
> use, wouldn't it?

The goal here is to make all programs bindable,
and to optimize things a bit.
If I wanted to allow forward referencing I
could do it very easily in the interpreter.
I happen to believe that the lack of (easy)
forward referencing is ultimately good for your sanity
and the sanity of the person trying to understand
your code.

Regards,
     Rob Craig
     Rapid Deployment Software
     http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

15. Re: 2 Pass Binder

-------Phoenix-Boundary-07081998-
Content-type: text/plain; charset=ISO-8859-1
Content-transfer-encoding: Quoted-printable

Robert Craig wrote:

>Craig writes:
> Does a 2 pass binding process offer the possibility of
> forward referencing without routine_id()=3F
> On second thought, that would cause some divisiveness
> between code intended for registered/nonregistered
> use, wouldn't it=3F
>
>The goal here is to make all programs bindable,
>and to optimize things a bit.
>If I wanted to allow forward referencing I
>could do it very easily in the interpreter.

Ah, I see. Toldja I didn't know squat about
interpreters; this proves it :).

>I happen to believe that the lack of (easy)
>forward referencing is ultimately good for your sanity
>and the sanity of the person trying to understand
>your code.

Agreed, completely.  My question wasn't a veiled request
for forward referencing; just curiosity, which has now been
satisfied.

Thanks,
Craig
--------------------------------------------
A statistician can have his head in an oven
and his feet in ice, and he will say that on
the average he feels fine.
-- Anonymous

-------Phoenix-Boundary-07081998---

new topic     » goto parent     » topic index » view message » categorize

16. Re: 2 Pass Binder

>     Why not on the FIRST PASS of bind, scan the source and build a symbol
>     table that contains
>     1: any time a constant or variable is used
>     2: any time a function is used
>     3: any time a procedure is used
>     The final result is symbol table containing a list of each item used.
>     The next pass you do the real bind and anything that is not in the
>     the symbol table is thrown away.
>Bernie

Oh and don't forget...
  4: any time a type is used

Lionel


______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com

new topic     » goto parent     » topic index » view message » categorize

17. Re: 2 Pass Binder

Bernie Ryan wrote:

>   To solve the routine id problem just scan from the bottom up.

Bernie,

Let's assume I have the following (pseudo-code) program:

   function sqr (object x)
      return x * x
   end function

   function sqrt (object x)
      return sqrt (x)
   end function

   constant commands = {"sqr", "sqrt"}

   object   operand
   sequence routine_name
   integer  choice

   puts (1, "You have the following options:\n\n")
   for i = 1 to length (commands) do
      puts (1, ('0' + i) & ") " & commands[i] & "\n") -- "i) name\n"
   end for
   puts (1, "\nEnter number of choice: ")

   choice = get_number (0)

   puts (1, "\n\nEnter object to apply to: ")

   operand = get_object (0)

   routine_name = commands[choice]

   ? call_func (routine_id (routine_name), {operand})

Now, how could I expect the binder to know to leave in the two
functions above? It HAS to leave both in the code, even though it
can't tell if either of them will ever be used.

This is just one example, true, but the idea can be applied in a
wide variety of ways. A simple remove-what-isn't-referenced works
fine for constants, variables, and maybe even types. But it won't
work for routines whenever routine_id is used with variables.
Either some part of the code has to be forced to change, or some
other approach has to be taken.


Rod

new topic     » goto parent     » topic index » view message » categorize

18. Re: 2 Pass Binder

Rod
  I have to admit that is a problem.
  I guess I better not write any binders.
Bernie

new topic     » goto parent     » topic index » view message » categorize

19. Re: 2 Pass Binder

EU>   function sqr (object x)
EU>      return x * x
EU>   end function

EU>   function sqrt (object x)
EU>      return sqrt (x)
EU>   end function

EU>   constant commands = {"sqr", "sqrt"}

EU>   object   operand
EU>   sequence routine_name
EU>   integer  choice

EU>   puts (1, "You have the following options:\n\n")
EU>   for i = 1 to length (commands) do
EU>      puts (1, ('0' + i) & ") " & commands[i] & "\n") -- "i) name\n"
EU>   end for
EU>   puts (1, "\nEnter number of choice: ")

EU>   choice = get_number (0)

EU>   puts (1, "\n\nEnter object to apply to: ")

EU>   operand = get_object (0)

EU>   routine_name = commands[choice]

EU>   ? call_func (routine_id (routine_name), {operand})

EU>Now, how could I expect the binder to know to leave in the two
EU>functions above? It HAS to leave both in the code, even though it
EU>can't tell if either of them will ever be used.


EU>Rod

With this, though, a smart binder could do the following:
1. see that commands is a constant
2. see that the argument to routine_id is an element of commands
3. know to leave in any routines named in commands

Since many programs do have routines that aren't used, it would leave
these out even though it uses routine_ids. For example, if you included
get.e and used get(0) instead of get_object(0), the binder would know ro
remove everything that isn't used in the program or listed in commands.
So the binder could get rid of M_WAIT_KEY, wait_key(), prompt_number(),
prompt_string(), get_bytes() (and maybe some more with more detailed
analisys).

Jeffrey Fielding
JJProg at cyberbury.net
http://members.tripod.com/~JJProg/

new topic     » goto parent     » topic index » view message » categorize

20. Re: 2 Pass Binder

JJProg at CYBERBURY.NET wrote:

>EU>   routine_name = commands[choice]
>
>EU>   ? call_func (routine_id (routine_name), {operand})
>
>EU>Now, how could I expect the binder to know to leave in the two
>EU>functions above? It HAS to leave both in the code, even though it
>EU>can't tell if either of them will ever be used.
[...]
>With this, though, a smart binder could do the following:
>1. see that commands is a constant
>2. see that the argument to routine_id is an element of commands
>3. know to leave in any routines named in commands

Well, that's theoretically true, and that sort of behavior would
be desireable. But just as another example of how tricky this could
get... before sending my email, I looked over the code and realized
that, silly me, I had left "commands" as a local variable. Since in
my example I knew it wasn't going to change, I made it a constant
"for efficiency purposes."

The problem is, leaving "commands" as a variable, even modifying it
later on (to add other commands once the user clicks on a checkbox,
etc.) is an completely valid approach.

Now I doubt *I'd* write a program like this, but if it's
syntactically and logically valid, why would it be wrong for someone
else to do so? That's when the problems begin. The only way to get
around this seems to be somehow limiting the programmer's ability to
write such code--probably by eliminating the ability to pass variables
to routine_id.

Sure, you could try to make the binder smarter still, but even if
*this* case can be caught, the variations are nearly infinite...
you'll eventually reach a point at which the binder can't handle it.
Suppose your referenced routines consist of:

   commandname_parametertype

and the name of the function to call is constructed at runtime
based on options the user selects? Or, what if you want to test
individual routines by directly inputing their names and
executing them?

"No one does any of that!" PROBABLY true. But it's valid, isn't it?
And if it's valid, then it's a situation that has to be handled.
The point is, there's no way to correctly evaluate all possible
contexes (?) when "routine_id (var)" is encountered. The binder
would have to back up through every place where "var" is set,
everywhere where a slice of "var" is set, every location where
a variable that var is set to gets set. In this miniscule example
alone, the binder would have to back up through:

   routine_id (routine_name) -->
   routine_name = commands[choice] -->
   constant commands = {...} -->
      BINDER: good, "commands" is a constant. Is "choice"? -->
      choice = get_number (0) --> (assume get_number is built-in,
         or things get worse...)
         BINDER: no, "choice" is always undetermined. We need to
            account for every element of "commands" -->
   BINDER: adds routine named commands[1] to the table
    ...
   BINDER: adds routine named commands[length(commands)] to the table

I imagine that for larger programs, or use of expressions (&, etc.),
the complexity could increase quite rapidly. Even then, you're
still making some assumptions that may not be valid. And again,
heaven forbid that after backing through all assignments you wind
up not having enough data to construct all potential literals.

It seems clear that you'd be better off just leaving all routines
in rather than taking this approach. You'll either wind up limiting
routine_id, or only being able to do this on programs that have no
calls to routine_id, or leaving open the possibility of writing
programs that occasionally give "invalid routine name" errors at
runtime.


Rod

new topic     » goto parent     » topic index » view message » categorize

21. Re: 2 Pass Binder

If anyone wants to see what a *single* pass shrouder might look like, I
posted a shrouder of weeks back.

I was written so that people could bind code that uses routine_id, and will
work correctly as long as you only use string constants in routine_id.

-- David Cuny

new topic     » goto parent     » topic index » view message » categorize

22. Re: 2 Pass Binder

EU>JJProg at CYBERBURY.NET wrote:

EU>>EU>   routine_name = commands[choice]
EU>>
EU>>EU>   ? call_func (routine_id (routine_name), {operand})
EU>>
EU>>EU>Now, how could I expect the binder to know to leave in the two
EU>>EU>functions above? It HAS to leave both in the code, even though it
EU>>EU>can't tell if either of them will ever be used.
EU>[...]
EU>>With this, though, a smart binder could do the following:
EU>>1. see that commands is a constant
EU>>2. see that the argument to routine_id is an element of commands
EU>>3. know to leave in any routines named in commands

EU>Well, that's theoretically true, and that sort of behavior would
EU>be desireable. But just as another example of how tricky this could
EU>get... before sending my email, I looked over the code and realized
EU>that, silly me, I had left "commands" as a local variable. Since in
EU>my example I knew it wasn't going to change, I made it a constant
EU>"for efficiency purposes."

EU>The problem is, leaving "commands" as a variable, even modifying it
EU>later on (to add other commands once the user clicks on a checkbox,
EU>etc.) is an completely valid approach.

EU>Now I doubt *I'd* write a program like this, but if it's
EU>syntactically and logically valid, why would it be wrong for someone
EU>else to do so? That's when the problems begin. The only way to get
EU>around this seems to be somehow limiting the programmer's ability to
EU>write such code--probably by eliminating the ability to pass variables
EU>to routine_id.

Not nessicarily. If the binder couldn't be sure that a particular
routine wasn't used, it would just have to include it anyway. It would
still be able to get rid of routines that it was sure wasn't used. Also,
a really smart interpreter could see where the variable is modified that
stores the names of the routines, and try to figure out what is used
from there.

EU>Sure, you could try to make the binder smarter still, but even if
EU>*this* case can be caught, the variations are nearly infinite...
EU>you'll eventually reach a point at which the binder can't handle it.
EU>Suppose your referenced routines consist of:

EU>   commandname_parametertype

EU>and the name of the function to call is constructed at runtime
EU>based on options the user selects? Or, what if you want to test
EU>individual routines by directly inputing their names and
EU>executing them?

EU>"No one does any of that!" PROBABLY true. But it's valid, isn't it?
EU>And if it's valid, then it's a situation that has to be handled.
EU>The point is, there's no way to correctly evaluate all possible
EU>contexes (?) when "routine_id (var)" is encountered. The binder
EU>would have to back up through every place where "var" is set,
EU>everywhere where a slice of "var" is set, every location where
EU>a variable that var is set to gets set. In this miniscule example
EU>alone, the binder would have to back up through:

Actually, I have used dynamic construction of routine names to spcify
the types of arguments. I did this to construct an Euphoria interpreter
for my compiled Euphoria bytecodes (I've been working on a Euphoria
assembly language and a compiler and interpreter for it). Still, a smart
binder could figure it out because it would see:

1. I start out with a constant name
2. I add either 'l' or 'v' to the end through a for loop and if
statements depending on the type of each argument.
3. The number of arguments is constant.

I agree with you, though, that if the routine name was totally
unpredictable (like using gets(0) to get a routine name), the binder
would not be able to scrap _any_ routines _in the current scope_. For
example:

include somefile.e
procedure a()
        ...
end procedure
procedure b()
        ...
end procedure
sequence name
name = gets(0)
call_proc(routine_id(name[1..length(name)-1]),{})

The binder couldn't get rid of a, b, or any global routines defined in
somefile.e. It could get rid of any non-global routines in somefile.e
that aren't referenced by any of the global routines.


EU>   routine_id (routine_name) -->
EU>   routine_name = commands[choice] -->
EU>   constant commands = {...} -->
EU>      BINDER: good, "commands" is a constant. Is "choice"? -->
EU>      choice = get_number (0) --> (assume get_number is built-in,
EU>         or things get worse...)
EU>         BINDER: no, "choice" is always undetermined. We need to
EU>            account for every element of "commands" -->
EU>   BINDER: adds routine named commands[1] to the table
EU>    ...
EU>   BINDER: adds routine named commands[length(commands)] to the table

EU>I imagine that for larger programs, or use of expressions (&, etc.),
EU>the complexity could increase quite rapidly. Even then, you're
EU>still making some assumptions that may not be valid. And again,
EU>heaven forbid that after backing through all assignments you wind
EU>up not having enough data to construct all potential literals.

EU>It seems clear that you'd be better off just leaving all routines
EU>in rather than taking this approach. You'll either wind up limiting
EU>routine_id, or only being able to do this on programs that have no
EU>calls to routine_id, or leaving open the possibility of writing
EU>programs that occasionally give "invalid routine name" errors at
EU>runtime.


EU>Rod


Jeffrey Fielding
JJProg at cyberbury.net
http://members.tripod.com/~JJProg/

new topic     » goto parent     » topic index » view message » categorize

23. Re: 2 Pass Binder

JJProg at CYBERBURY.NET wrote:

>EU>Now I doubt *I'd* write a program like this, but if it's
>EU>syntactically and logically valid, why would it be wrong for someone
>EU>else to do so? That's when the problems begin. The only way to get
>EU>around this seems to be somehow limiting the programmer's ability to
>EU>write such code--probably by eliminating the ability to pass variables
>EU>to routine_id.
>
>Not nessicarily. If the binder couldn't be sure that a particular
>routine wasn't used, it would just have to include it anyway. It would
>still be able to get rid of routines that it was sure wasn't used. Also,
>a really smart interpreter could see where the variable is modified that
>stores the names of the routines, and try to figure out what is used
>from there.

But that's my point... you might be able to do that for simple
code, but sooner or later it breaks down. You wouldn't even be
able to tell which routines were definitely not used. Why?
Because, in order to arrive at a literal for every instance of
routine_id that is given a variable, you almost have to execute
the program while still binding--and you'd have to try to do it
backwards!...

Whenever a binder following this method would encounter the code
"routine_id (var)", it would have no immediate knowledge of what
"var" was. Sure, the line prior to it might read "var = 'MyFunc'",
a case you could hardwire to be handled easily. But what if "var"
was passed in as a parameter to the enclosing routine? (or had some
other messy source, but let's stick with this one for now.) Not
likely, but possible.

So now the binder has to go back and find every call to that
routine, and determine all possible values of that parameter. If
you or Rob would be up to taking the challenge of writing a binder
that could do all that, hey, more power to you, but if I was
writing that kind of a binder, and it saw that several of those
calls had variables passed as parameters instead of literals, I
think I'd just have the thing give up and retain every routine.

Or if it found only one call, but the call was something like:

   Found = 0
   for i = 1 to length(s) do
      if (s[i] = k) then
         Found = 1
         routine_name = construct_routine_name (i)
         exit
      end if
   end for

   if (Found) then
      exec_routine (routine_name) -- EEK!
   end if

I think I'd have the binder just keep everything in this case, too.
Having it nested in an "if" is one thing; but when the parameter
itself is the result of a function call, well, it's probably better
to stop right there rather than keep running the program in reverse...

<snip>

>Actually, I have used dynamic construction of routine names to spcify
>the types of arguments. I did this to construct an Euphoria interpreter
>for my compiled Euphoria bytecodes (I've been working on a Euphoria
>assembly language and a compiler and interpreter for it).

Ah yes, you were working on the Euphoria OS, right? Sorry about
switching subjects mid-stream, but how is that going? It sounds
like a pretty neat idea.

<snip>

>I agree with you, though, that if the routine name was totally
>unpredictable (like using gets(0) to get a routine name), the binder
>would not be able to scrap _any_ routines _in the current scope_. For
>example:
>
>include somefile.e
>procedure a()
>        ...
>end procedure
>procedure b()
>        ...
>end procedure
>sequence name
>name = gets(0)
>
>The binder couldn't get rid of a, b, or any global routines defined in
>somefile.e. It could get rid of any non-global routines in somefile.e
>that aren't referenced by any of the global routines.

Hmmm, almost. If the local routine is called by a local routine
that's called by a global routine, it still needs to be included.

The only way any routine could be left out would be if:

  1) it were local
  2) no local routines (within the same scope, including itself)
used routine_id with a variable passed to it, and
  3) there was no direct or indirect calling of the routine from
a global routine in the same scope.

I wouldn't think a typical, large program that used routine_id
would have a lot of routines that would fit those criteria. Any
such routines it did have would have to be either a logic error
on the part of the programmer, or deliberate (to test workings of
the interpreter, etc.)

Hmm... perhaps that's what this all boils down to. Should logic
errors ever be optimized away? For example, I've often put code
like this in a program:

   for i = 1 to 1000000 do end for

even though it doesn't appear to do anything. I've even
employed empty procedures and functions a time or two.

Is it wise to assume the programmer made a mistake in these
cases? If so, wouldn't it be better to alert him to it rather
than "throwing it away"? Does such a feature have worth even
as a bind option? If the code doesn't belong there, shouldn't
the programmer be told about it so that he can remove it (or
rewrite it like he originally intended), rather than let the
error go unnoticed, for months or even years? Please note, I'm
not saying the feature doesn't have worth, etc.; I'm just
playing "devil's advocate" here. blink


Rod

new topic     » goto parent     » topic index » view message » categorize

24. Re: 2 Pass Binder

What about simply adding a directive (or expanding the "with/without"
commands) to allow the user to direct the inclusion/exclusion of routines?
 Some possible syntaxes are:

with required_routines
        or
with optional_routines
        or
with proc1, proc2, func1, type1, proc3
include filename

Or something along those lines.

Also, a further enhancement of the with command could be a "with(out)
inlining" to request that a routine be inlined if possible.

Joe

-----Original Message-----
From:   Robert Craig [SMTP:rds at ATTCANADA.NET]
Sent:   Tuesday, August 17, 1999 10:58 PM
To:     EUPHORIA at LISTSERV.MUOHIO.EDU
Subject:        Re: 2 Pass Binder

Craig writes:
> Does a 2 pass binding process offer the possibility of
> forward referencing without routine_id()?
> On second thought, that would cause some divisiveness
> between code intended for registered/nonregistered
> use, wouldn't it?

The goal here is to make all programs bindable,
and to optimize things a bit.
If I wanted to allow forward referencing I
could do it very easily in the interpreter.
I happen to believe that the lack of (easy)
forward referencing is ultimately good for your sanity
and the sanity of the person trying to understand
your code.

Regards,
     Rob Craig
     Rapid Deployment Software
     http://www.RapidEuphoria.com
________________________________________________________
NetZero - We believe in a FREE Internet.  Shouldn't you?
Get your FREE Internet Access and Email at
http://www.netzero.net/download/index.html

new topic     » goto parent     » topic index » view message » categorize

25. Re: 2 Pass Binder

Couldn't the interpreter auto-detect when inlining would be and when it
wouldn't be faster ?
I mean based on cache-size of the proccesor, etc.
Now, I think of it, Robert, why not create some mixture between inlining and
calling ?
I mean, all speed benefits of inlining could also be gained without
inlining. The things that would change during the inlining 'procces' could
also be changed at the beginning without the actual inlining. Its rather the
redunant type checks, variable passings, and stack operations which could be
limited by 'preproccesing' the code anyway.

(try to have the interpreter do only that work, that really needs to be done
at run-time)

Example:

for index = 1 to length(s) -1 do
    s[index] = positive (s[index+1] - s[index])
end for

The above, could in the preprocces stage, internally, be optimized to very
fast and efficient code. For example, we *know* index will never be an
illegal value. (a special knowledge with for-loops-variables). And index+1
equals index, at the next iteration, the value need not be looked up twice.

The question for the interpreter merely is: what *does* change with each
iteration ?
And thus: at what points could the program flow be affected by such a
change, and where not ?

For example:

if x then
 if x thern
end if
end if

Would currently make the interpreter consider x twice.

I know, some of these ideas are hard, if not impossible to implement, but
some are not.
It is do-able to check which variables change without a loop-construct and
which don't ..

And such is true with inlining-advantages as well.

Ralf N.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu