pop Π£Π±ΡΠ°ΡΡ Π²Π΅ΡΡ Π½ΠΈΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΠΈΠ· ΡΡΠ΅ΠΊΠ°
STOP ΠΠΎΠ½Π΅Ρ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΊΠΎΠΌΠ°Π½Π΄
ΠΠΎΠ³Π΄Π° Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ, Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π²ΡΡΠΈΡΠ»ΡΠ΅ΡΡΡ ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π² x, ΠΊΠ°ΠΊ ΠΈ ΡΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ°Π½ΠΈΡΡ . ΠΠΎΡΠ»Π΅Π΄Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π° pop ΡΠ΄Π°Π»ΡΠ΅Ρ ΠΈΠ· ΡΡΠ΅ΠΊΠ° Π²Π΅ΡΡ Π½ΠΈΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π½ΡΠΆΠ΅Π½.
Π‘ΡΠ΅ΠΊΠΎΠ²ΡΠ΅ ΠΌΠ°ΡΠΈΠ½Ρ ΠΎΠ±ΡΡΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΡΠΎΡΡΡΡ ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ°ΡΠΎΡΠΎΠ², ΠΈ Π½Π°Ρ ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ°ΡΠΎΡ ΡΠΎΠΆΠ΅ Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ: ΡΡΠΎ ΠΏΡΠΎΡΡΠΎ ΠΌΠ°ΡΡΠΈΠ², ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΈ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Ρ. ΠΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡ ΡΠΎΠ±ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Π½ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ: ΠΊΠ°ΠΆΠ΄Π°Ρ ΠΈΠ· Π½ΠΈΡ ΡΡΡΡ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ»Π΅Π΄ΡΡΡ Π·Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ. ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Ρ ΠΌΠΎΠ³ΡΡ ΡΠΆΠ΅ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡΡ Π² ΡΡΠ΅ΠΊΠ΅, ΠΊΠ°ΠΊ Π±ΡΠ»ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π²ΡΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠ΅.
Π‘ΡΡΡΠΊΡΡΡΠ° ΡΠ°Π±Π»ΠΈΡΡ ΠΈΠΌΠ΅Π½ Π΄Π»Ρ hoc4 ΡΠΎΠ²ΠΏΠ°Π΄Π°Π΅Ρ Ρ ΡΠ°ΠΊΠΎΠ²ΠΎΠΉ Π΄Π»Ρ hoc3: ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΈΡ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈΡΡΡ Π² init.c, ΠΈ ΠΌΠ°ΡΠ΅ΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ, Π½Π°Ρ ΠΎΠ΄ΡΡΠΈΠ΅ΡΡ Π² math.c, ΠΎΠ΄Π½ΠΈ ΠΈ ΡΠ΅ ΠΆΠ΅. ΠΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠ° hoc4 ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½Π° Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠ΅ hoc3, Π½ΠΎ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ ΡΠΎΠ²Π΅ΡΡΠ΅Π½Π½ΠΎ ΠΈΠ½ΡΠ΅. ΠΠΎΠΎΠ±ΡΠ΅, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΏΠΎΡΠΎΠΆΠ΄Π°Π΅Ρ ΠΌΠ°ΡΠΈΠ½Π½ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΈ Π²ΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π΄Π»Ρ Π½ΠΈΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² ΡΠ»ΡΡΠ°Π΅ ΠΏΠΎΡΠ²Π»Π΅Π½ΠΈΡ VAR Π² Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΈ ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΡΡΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Ρ: ΠΊΠΎΠΌΠ°Π½Π΄Π° varpush, ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΠ°Π±Π»ΠΈΡΡ ΠΈΠΌΠ΅Π½ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π° eval, ΠΊΠΎΡΠΎΡΠ°Ρ Π·Π°ΠΌΠ΅Π½ΡΠ΅Ρ ΠΏΡΠΈ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΠ°Π±Π»ΠΈΡΡ ΠΈΠΌΠ΅Π½ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ. ΠΠΎΠ΄ Π΄Π»Ρ '*' ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΎΠ΄Π½Ρ ΠΊΠΎΠΌΠ°Π½Π΄Ρ mul, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Ρ Π΄Π»Ρ Π½Π΅Π΅ ΡΠΆΠ΅ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ Π² ΡΡΠ΅ΠΊΠ΅.
$ cat hoc.y
%{
#include "hoc.h"
#define code2(c1,c2) code(c1); code(c2)
#define code3(c1,c2,c3) code(c1); code(c2); code(c3)
%}
%union {
Symbol *sym; /* symbol table pointer */
Inst *inst; /* machine instruction */
}
%token <sym> NUMBER VAR BLTIN UNDEF
%right '='
%left '+'
%left '*' '/'
%left UNARYMINUS
%right '^' /* exponentiation */
%%
list: /* nothing */ | list '\n'
| list asgn '\n' { code2(pop, STOP); return 1; }
| list expr '\n' { code2(print, STOP); return 1; }
| list error '\n' { yyerrok; }
;
asgn: VAR '=' expr { code3(varpush, (Inst)$1, assign); }
;
expr: NUMBER { code2(constpush, (Inst)$1); }
| VAR { code3(varpush, (Inst)$1, eval); }
| asgn
| BLTIN '(' expr ')' { code2(bltin, (Inst)$1->u.ptr); }
| '(' expr ')'
| expr '+' expr { code(add); }
| expr '-' expr { code(sub); }
| expr '*' expr { code(mul); }
| expr '/' expr { code(div); }
| expr '^' expr { code(power); }
| '-' expr %prec UNARYMINUS { code (negate); }
;
%%
/* end of grammar */
...
Inst ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΈΠΏΠΎΠΌ Π΄Π°Π½Π½ΡΡ ΠΌΠ°ΡΠΈΠ½Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ (ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΡΠ½ΠΊΡΠΈΡ, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΡΡ int), ΠΊ ΠΎΠ±ΡΡΠΆΠ΄Π΅Π½ΠΈΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΌΡ Π²ΡΠΊΠΎΡΠ΅ Π²Π΅ΡΠ½Π΅ΠΌΡΡ. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΠΎ, ΡΡΠΎ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°ΠΌΠΈ Π΄Π»Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ code ΡΠ»ΡΠΆΠ°Ρ ΠΈΠΌΠ΅Π½Π° ΡΡΠ½ΠΊΡΠΈΠΉ, Ρ.Π΅. ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ Π½Π° ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ»ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΠ΅ Ρ Π½ΠΈΠΌΠΈ Π²Π΅Π»ΠΈΡΠΈΠ½Ρ.
ΠΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ»ΠΈ ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ main. Π’Π΅ΠΏΠ΅ΡΡ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π²ΠΎΠ·Π²ΡΠ°Ρ ΠΈΠ· Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡΠ° ΠΏΠΎΡΠ»Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° ΠΈΠ»ΠΈ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΈ ΠΏΠΎΡΠΎΠΆΠ΄Π΅Π½Π½ΡΠΉ ΠΊΠΎΠ΄ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ. ΠΡΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠΈ ΡΠ°ΠΉΠ»Π° yyparse Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π½ΡΠ»Ρ.
main(argc, argv) /* hoc4 */
char *argv[];
{
int fpecatch();
progname = argv[0];
init();
setjmp(begin);
signal(SIGFPE, fpecatch);
for (initcode(); yyparse(); initcode())
execute(prog);
return 0;
}
ΠΠ΅ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡ ΠΎΡΠ»ΠΈΡΠ°Π΅ΡΡΡ ΠΌΠ°Π»ΠΎ Π² ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ ΡΠ΅ΠΌ, ΡΡΠΎ ΡΠΈΡΠ»Π° ΡΠ»Π΅Π΄ΡΠ΅Ρ ΡΠΎΡ ΡΠ°Π½ΡΡΡ, Π° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π·Π°Π½Π΅ΡΡΠΈ ΠΈΡ Π² ΡΠ°Π±Π»ΠΈΡΡ ΠΈΠΌΠ΅Π½ Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ. ΠΠΈΠΆΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½Π°Ρ ΡΠ°ΡΡΡ yylex:
yylex() /* hoc4 */
...
if (Ρ == '.' || isdigit(c)) {
/* number */
double d;
ungetc(c, stdin);
scanf("%lf", &d);
yylval.sym = install("", NUMBER, d);
return NUMBER;
}
...
ΠΠ°ΠΆΠ΄ΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΡΡΠ΅ΠΊΠ° ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ°ΡΠΎΡΠ° ΡΠ²Π»ΡΠ΅ΡΡΡ Π²Π΅ΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΈΠ»ΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΌ Π½Π° Π·Π°ΠΏΠΈΡΡ Π² ΡΠ°Π±Π»ΠΈΡΠ΅ ΠΈΠΌΠ΅Π½; ΡΠΈΠΏ Π΄Π°Π½Π½ΡΡ ΡΡΠ΅ΠΊΠ° ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π²ΡΠ΅Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ². Π‘Π°ΠΌΠ° ΠΌΠ°ΡΠΈΠ½Π° ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΡΡΡ ΠΊΠ°ΠΊ ΠΌΠ°ΡΡΠΈΠ² ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ Π½Π° ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ, Π²ΡΠΏΠΎΠ»Π½ΡΡΡΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΡΠΈΠΏΠ° mul, ΠΈΠ»ΠΈ Π½Π° Π΄Π°Π½Π½ΡΠ΅ Π² ΡΠ°Π±Π»ΠΈΡΠ΅ ΠΈΠΌΠ΅Π½. Π€Π°ΠΉΠ» ΠΌΠ°ΠΊΡΠΎΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ hoc.h ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΊΠ»ΡΡΠΈΡΡ ΡΡΠΈ ΡΡΡΡΠΊΡΡΡΡ Π΄Π°Π½Π½ΡΡ ΠΈ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΉ Π΄Π»Ρ ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ°ΡΠΎΡΠ°, ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΈ Π±ΡΠ»ΠΈ Π΄ΠΎΡΡΡΠΏΠ½Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ Π² ΡΠ΅Π»ΠΎΠΌ. (ΠΡΡΠ°ΡΠΈ, ΠΌΡ ΠΏΡΠ΅Π΄ΠΏΠΎΡΠ»ΠΈ ΠΏΠΎΠΌΠ΅ΡΡΠΈΡΡ Π²ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π² ΠΎΠ΄ΠΈΠ½ ΡΠ°ΠΉΠ», Π° Π½Π΅ Π² Π΄Π²Π°, Ρ ΠΎΡΡ Π΄Π»Ρ Π±ΠΎΠ»ΡΡΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ Π΅Π΅ ΡΠ΅Π»Π΅ΡΠΎΠΎΠ±ΡΠ°Π·Π½ΠΎ ΡΠ°Π·Π΄Π΅Π»ΠΈΡΡ Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΉΠ»ΠΎΠ² Ρ ΡΠ΅ΠΌ, ΡΡΠΎΠ±Ρ Π²ΠΊΠ»ΡΡΠ°ΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· Π½ΠΈΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΌ, Π³Π΄Π΅ ΠΎΠ½ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π½ΡΠΆΠ΅Π½.)
$ cat hoc.h
typedef struct Symbol { /* symbol table entry */
char *name;
short type; /* VAR, BLTIN, UNDEF */
union {
double val; /* if VAR */
double (*ptr)(); /* if BLTIN */
} u;
struct Symbol *next; /* to link to another */
} Symbol;
Symbol *install(), *lookup();
typedef union Datum { /* interpreter stack type */
double val;
Symbol *sym;
} Datum;
extern Datum pop();
typedef int (*Inst)(); /* machine instruction */
#define STOP (Inst) 0
extern Inst prog[];
extern eval(), add(), sub(), mul(), div(), negate(), power();
extern assign(), bltin(), varpush(), constpush(), print();
$
ΠΡΠΎΡΠ΅Π΄ΡΡΡ, Π²ΡΠΏΠΎΠ»Π½ΡΡΡΠΈΠ΅ ΠΌΠ°ΡΠΈΠ½Π½ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΈ ΡΠΏΡΠ°Π²Π»ΡΡΡΠΈΠ΅ ΡΡΠ΅ΠΊΠΎΠΌ, Ρ ΡΠ°Π½ΡΡΡΡ Π² ΡΠ°ΠΉΠ»Π΅ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ code.c. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΡΠ°ΠΉΠ»Π° ΡΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΎΠΊΠΎΠ»ΠΎ 150 ΡΡΡΠΎΠΊ, ΠΌΡ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ Π΅Π³ΠΎ ΠΏΠΎ ΡΠ°ΡΡΡΠΌ:
$ cat code.c
#include "hoc.h"
#include "y.tab.h"
#define NSTACK 256
static Datum stack[NSTACK]; /* the stack */
static Datum *stackp; /* next free spot on stack */
#define NPROG 2000
Inst prog[NPROG]; /* the machine */
Inst *progp; /* next free spot for code generation */
Inst *pc; /* program counter during execution */
initcode() /* initialize for code generation */
{
stackp = stack;
progp = prog;
}
...
Π£ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΡΠ΅ΠΊΠΎΠΌ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΡΡΠ΅ΠΌ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΉ ΠΊ Π΄Π²ΡΠΌ ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ°ΠΌ push ΠΈ pop:
push(d) /* push d onto stack */
Datum d;
{
if (stackp >= &stack[NSTACK])
execerror("stack overflow", (char*)0);
*stackp++ = d;
}
Datum pop() /* pop and return top elem from stack */
{
if (stackp <= stack)
execerror("stack underflow", (char*)0);
return *--stackp;
}
ΠΠ°ΡΠΈΠ½Π½ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΠΎΠ·Π΄Π°ΡΡΡΡ Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΡΠ°Π·Π±ΠΎΡΠ° ΠΏΡΠΈ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΈ ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ code, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΎΡΡΠΎ Π²Π½ΠΎΡΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π½Π° ΠΏΠ΅ΡΠ²ΠΎΠ΅ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠ΅ ΠΌΠ΅ΡΡΠΎ ΠΌΠ°ΡΡΠΈΠ²Π° prog. ΠΠ½Π° Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π°Π΄ΡΠ΅Ρ ΠΊΠΎΠΌΠ°Π½Π΄Ρ (ΠΊΠΎΡΠΎΡΡΠΉ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π² hoc4):
Inst *code(f) /* install one instruction or operand */
Inst f;
{
Inst *oprogp = progp;
if (progp >= &prog[NPROG])
execerror("program too big", (char*)0);
*progp++ = f;
return oprogp;
}
ΠΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΌΠ°ΡΠΈΠ½Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΠ°Π½ΡΠ°ΡΡΠΈΡΠ΅ΡΠΊΠΈ ΡΡΠΈΠ²ΠΈΠ°Π»ΡΠ½ΠΎ, Π° ΠΊΠ°ΠΊ ΠΌΠ°Π»Π° ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ°, ΠΊΠΎΡΠΎΡΠ°Ρ "Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ" ΠΌΠ°ΡΠΈΠ½Π½ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ, ΠΊΠΎΠ³Π΄Π° ΡΠΆΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ Π²ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ!
execute(p) /* run the machine */
Inst *p;
{
for (pc = p; *pc != STOP; )
(*(*pc++))();
}
Π ΡΠΈΠΊΠ»Π΅ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌΠ°Ρ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ, Π½Π° ΠΊΠΎΡΠΎΡΡΡ Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΡΡΠ΅ΡΡΠΈΠΊ ΠΊΠΎΠΌΠ°Π½Π΄ pc. ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ pc ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠΌ Π²ΡΠ±ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ. ΠΠΎΠΌΠ°Π½Π΄Π° Ρ ΠΊΠΎΠ΄ΠΎΠΌ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ STOP Π·Π°Π²Π΅ΡΡΠ°Π΅Ρ ΡΠΈΠΊΠ». ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ constpush ΠΈ varpush, ΡΠ°ΠΌΠΈ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°ΡΡ pc, ΡΡΠΎΠ±Ρ "ΠΏΠ΅ΡΠ΅ΡΠΊΠΎΡΠΈΡΡ" ΡΠ΅ΡΠ΅Π· Π»ΡΠ±ΡΠ΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ, ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ Π·Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ.
constpush() /* push constant onto stack */
{
Datum d;
d.val = ((Symbol*)*pc++)->u.val;
push(d);
}
varpush() /* push variable onto stack */
{
Datum d;
d.sym = (Symbol*)(*pc++);
push(d);
}
ΠΡΡΠ°Π²ΡΠ°ΡΡΡ ΡΠ°ΡΡΡ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΠΌΠ°ΡΠΈΠ½Ρ ΠΏΡΠΎΡΡΠ°. Π’Π°ΠΊ, Π°ΡΠΈΡΠΌΠ΅ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π² ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ ΡΠ΅ ΠΆΠ΅, ΠΈ ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΠΎΠ½ΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°Π·ΡΠ°. ΠΠΈΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ add:
add() /* add top two elems on stack */
{
Datum d1, d2;
d2 = pop();
d1 = pop();
d1.val += d2.val;
push(d1);
}
ΠΡΡΠ³ΠΈΠ΅ ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΎΡΡΡ:
eval() /* evaluate variable on stack */
{
Datum d;
d = pop();
if (d.sym->type == UNDEF)
execerror("undefined variable", d.sym->name);
d.val = d.sym->u.val;
push(d);
}
assign() /* assign top value to next value */
{
Datum d1, d2;
d1 = pop();
d2 = pop();
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
execerror("assignment to non-variable", d1.sym->name);
d1.sym->u.val = d2.val;
d1.sym->type = VAR;
push(d2);
}
print() /* pop top value from stack, print it */
{
Datum d;
d = pop();
printf("\t%.8g\n", d.val);