How to implement LOOP in a FORTH interpreter written in C

I write a simple stack-based language in C and wondered how I should implement a loop structure of some type and / or characters in the form. Since the code is a little long for this page (over 200 lines), I put it in the GitHub repository .

EDIT: The main program is in the file stack.c.

EDIT: The code just accepts the input words, sort of like FORTH. It uses scanfand works from left to right. He then uses the series ifand strcmpto decide what to do. It really is.

+5
source share
4 answers

Forth's approach is to add a separate loop stack next to the data stack. Then you define the operations that work with this loop stack. For instance:

5 0 DO I . LOOP

Will be printed

0 1 2 3 4

How it works:

  • DO moves index (0) and control (5) onto the loop stack.
  • I copies the top of the loop stack to the data stack.
  • LOOPincreases the index (top of the loop stack). If the index is smaller than the control (one below the top of the loop stack), it re-runs the commands from DOback to LOOP. If the index is> =, then it pops the index and control out of the loop stack, and control resumes as usual.
+9
source

" ". Postscript, , , Forth ( , ).

repeat. , loop , exit , .

:

int proc  **repeat**  -

, repeat, ( , ), ( ).

( , Forth "" ), "" , , , . , .

, . :

operand: -empty-
execute: <stdin>

2 {(Hello World!\n) print} repeat.

2 .

operand: 2
execute: <stdin>

(*) .

operand: 2 {(Hello World!\n) print}
execute: <stdin>

repeat.

operand: 2 {(Hello World!\n) print}
execute: <stdin> repeat

Repeat: expects operands: int proc
    if int<0 Error
    if int==0 return //do nothing
    push `repeat` itself on exec stack
    push quoted proc on exec stack
    push int-1 on exec stack
    push "executable" proc on exec stack

( ) :

operand: -empty-
execute: <stdin> repeat {(Hello World!\n) print} 1 **{(Hello World!\n) print}**

exec, "Hello World!", , op.

operand: 1
execute: <stdin> repeat {(Hello World!\n) print}

, op.

operand: 1 {(Hello World!\n) print}
execute: <stdin> repeat

! ( , ).

, .

Edit

, , , , -, . , . , , !

, ( ( )). - :

struct object {
    int type;
    union {
        int i;
        void (*command)(context *);
    } u;
};

struct dict {
    int sz;
    struct rec {
        char *key;
        object val;
    }  data[]; //think resizable!
};

. : . , . .

. . , .

- Turing Complete. , , ( ): , !


*. , Postscript , . Lisp. Postscript literal/executable, cvx cvlit xcheck. . , "" - - (.. ). - repeat cvx . , postcript repeat :

Repeat: expects operands: int proc
    if int<0 Error
    if int==0 return //do nothing
    push `repeat` itself on exec stack
    push 'cvx' on the exec stack
    push cvlit(proc) on exec stack
    push int-1 on exec stack
    push "executable" proc on exec stack

, .

, , , : repeat , . , ghostscript - @repeat-continue @. , . exec; .

, repeat :

int proc  **repeat**  -
    if int<0 Error
    if int==0 return //do nothing
    push null on exec stack   <--- this marks our "frame"
    push int-1 on exec stack
    push proc on exec stack
    push '@repeat-continue' on exec stack
    push executable proc on exec stack

.

@repeat-continue
    peek proc from exec stack
    peek int from exec stack
    if int==0 clear-to-null and return
    push '@repeat-continue' on exec stack
    push executable proc on exec stack

, exit , exec "" . 2- null . 1- .

+6

Forth-like, Forth ( - - ).

, until . , range jump, , , stack.c cmd .

0
dup . 1 + dup 5 > until
.

0 1 2 3 4 5 6 . , . LSE64 .

+2

Here's a blog post in which DO / LOOP, BEGIN / UNTIL, WHILE / REPEAT, etc. are being implemented in my small TransForth project: http://blogs.msdn.com/b/ashleyf/archive/2011/02/06/loopty-do-i-lolo.aspx

Since then I have changed my mind and completely rely on recursion without such looped words.

Hope this helps, have fun!

+1
source

All Articles