Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.compilers > #895 > unrolled thread

interpreter: how is it possible to interpret nested IF ELSE ENDIF ????

Started byJens Kallup <jkallup@web.de>
First post2013-05-15 07:42 +0200
Last post2013-06-19 03:43 -0700
Articles 3 — 3 participants

Back to article view | Back to comp.compilers


Contents

  interpreter: how is it possible to interpret nested IF ELSE ENDIF ???? Jens Kallup <jkallup@web.de> - 2013-05-15 07:42 +0200
    Re: interpreter: how is it possible to interpret nested IF ELSE ENDIF ???? Aleksey Demakov <ademakov@gmail.com> - 2013-05-31 16:07 +0400
    Re: interpreter: how is it possible to interpret nested IF ELSE ENDIF ???? mertesthomas@gmail.com - 2013-06-19 03:43 -0700

#895 — interpreter: how is it possible to interpret nested IF ELSE ENDIF ????

FromJens Kallup <jkallup@web.de>
Date2013-05-15 07:42 +0200
Subjectinterpreter: how is it possible to interpret nested IF ELSE ENDIF ????
Message-ID<13-05-009@comp.compilers>
Hello,

like the topic says:

a give construct should be interpret through a single pass???:

IF 2 == 3
   print "not print"

   IF 2 == 3
     print "not"
   ELSE
     print "wrong1"
   ENDIF

   print "3"

ELSE

   print "this"

ENDIF


Thanks for helping
Jens
[My usual advice is to translate the source to something easy to
interpret like an AST, then run your interpreter on that.  Trying
to jump around in the source code and remember when to parse what
and to avoid side effects when parsing through code you're supposed
to skip is miserable. -John]

[toc] | [next] | [standalone]


#910

FromAleksey Demakov <ademakov@gmail.com>
Date2013-05-31 16:07 +0400
Message-ID<13-05-024@comp.compilers>
In reply to#895
Hi,

Just have in your interpreter a structure that has all the information
required to execute one statement. To support nested statements every
such structure should have a pointer to the parent structure. You will
have a global pointer to the currently executing statement. When
interpreter meets a nested statement it creates a new structure, saves
the current statement in the parent pointer and makes the new
structure current. When the interpreter reaches the end of the current
statement it takes its parent pointer and makes it current.

For if-else-endif statement you will need to remember within the
structure if the if-condition was met. Depending on it you set a
global skip-flag when entering either of the two if branches. When the
flag is set the statements like assignments and procedure calls are
just ignored. But for nested if-else-endif statements the interpreter
still creates nested structures and observes the described above order
of entering and leaving them.

But on entering a branch before setting the skip flag it is required
to save its previous value and on leaving a branch the previous value
has to be restored.

Such implementation technique works well for such simple cases as
#ifdefs of c preprocessor.

But when it is necessary to handle something more complicated like
loop statements or gotos then it becomes more practical to have some
sort of intermediate representation like ASTs or bytecodes.

Regards,
Aleksey

[toc] | [prev] | [next] | [standalone]


#927

Frommertesthomas@gmail.com
Date2013-06-19 03:43 -0700
Message-ID<13-06-017@comp.compilers>
In reply to#895
Am Mittwoch, 15. Mai 2013 07:42:19 UTC+2 schrieb Jens Kallup:
> Hello,
> like the topic says:
> a give construct should be interpret through a single pass???:
>
> IF 2 == 3
>    print "not print"
>    IF 2 == 3
>      print "not"
>    ELSE
>      print "wrong1"
>    ENDIF
>    print "3"
> ELSE
>    print "this"
> ENDIF

In my BASIC interpreter and in my make utility I use source code
interpretation (when I started to write the BASIC interpreter I
expected to encounter BASIC programs with self modifying code. :-)
Therefore I used source code interpretation).

For source code interpretation you need functions to skip some code.
E.g.:
- Skip to next ELSE or ENDIF
- Skip to next ENDIF
Be careful:
  This functions must check if an IF statement is encountered.
  In this case they must call "Skip to next ENDIF"
  recursively and continue skipping after the ENDIF.

Then you can essentially work as follows:
- When an IF is taken you can continue executing statements.
- When an IF is not taken you use "Skip to next ELSE or ENDIF"
  and continue executing after the ELSE or ENDIF.
- When you approach an ELSE you use "Skip to next ENDIF"
  and continue executing after the ENDIF.
- When you approach an ENDIF you can continue executing statements.

There are also corner cases, like what to do when the end of
a file is reached during the skipping.

If you have also ELSIF statements the situation becomes
more complicated, but it is also solveable.

If you are interested in the details:
The Bas7 interpreter is described here:
http://seed7.sourceforge.net/scrshots/bas7.htm
There is a link to the source code in the top right area of the page.
The functions to skip code (regarding IF statements) are:
find_then
find_else
find_end_if
find_else_elseif_or_end_if

The functions will probably not fit to your interpreter, but you
might get some ideas from them.


Regards,
Thomas Mertes

--
Seed7 Homepage:  http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.
[This can work, but it's a lot easier to translate the source code
into an AST and interpret that.  If the source changes, translate it
again. -John]

[toc] | [prev] | [standalone]


Back to top | Article view | comp.compilers


csiph-web