Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX β€” ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ срСда программирования». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 69

Автор Π‘Ρ€Π°ΠΉΠ°Π½ ΠšΠ΅Ρ€Π½ΠΈΠ³Π°Π½

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);