}Inst *code(f) /* install one instruction or operand */ Inst f;{ Inst *oprogp = progp; if (progp >= &prog[NPROG]) execerror("expression too complicated", (char*)0); *progp++ = f; return oprogp;}execute(p) Inst *p;{ for (pc = p; *pc != STOP; ) (*(*pc++))();}3.6.2
fib{ a=0 b=1 while(b<1000) { c=b b=a+b a=c print(c) }}3.6.3
fib2{ n=0 a=0 b=1 while(b<10000000){ n=n+1 c=b b=a+b a=c print(b) } print(n)}3.6.4
hoc.htypedef 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)0extern Inst prog[], *progp, *code();extern eval(), add(), sub(), mul(), div(), negate(), power();extern assign(), bltin(), varpush(), constpush(), print();extern prexpr();extern gt(), lt(), eq(), ge(), le(), ne(), and(), or(), not();extern ifcode(), whilecode();3.6.5
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 PRINT VAR BLTIN UNDEF WHILE IF ELSE%type <inst> stmt asgn expr stmtlist cond while if end%right '='%left OR%left AND%left GT GE LT LE EQ NE%left '+' '-'%left '*' '/'%left UNARYMINUS NOT%right%%list: /* nothing */ | list '\n' | list asgn '\n' { code2(pop, STOP); return 1; } | list stmt '\n' { code(STOP); return 1; } | list expr '\n' { code2(print, STOP); return 1; } | list error '\n' { yyerrok; } ;asgn: VAR '=' expr { $$=$3; code3(varpush,(Inst)$1.assign); } ;stmt: expr { code(pop); } | PRINT expr { code(prexpr); $$ = $2; } | while cond stmt end { ($1)[1] = (Inst)$3; /* body of loop */ ($1)[2] = (Inst)$4; } /* end, if cond fails */ | if cond stmt end { /* else-less if */ ($1)[1] = (Inst)$3; /* thenpart */ ($1)[2] = (Inst)$4; } /* end, if cond fails */ | if cond stmt end ELSE stmt end { /* if with else */ ($1)[1] = (Inst)$3; /* thenpart */ ($1)[2] = (Inst)$6; /* elsepart */ ($1)[3] = (Inst)$7; } /* end, if cond fails */ | '{' stmtlist '}' { $$ = $2; }