/ bcpl.c
bcpl.c
1 // Helper functions for bcpl.h 2 3 #include "bcpl.h" 4 #include "emas.h" // for TERMINATOR 5 6 #include <ctype.h> // for isdigit() 7 #include <string.h> // for strcmp() 8 9 // Which file descriptors should BCPL's input and output use? 10 // We use (FILE *)0 as a synonym for stdin / stdout since 11 // we can't initialise statically because stdin and stdout 12 // are not constants on some systems. 13 FILE *bcpl_INPUT_fp=(FILE *)0; 14 FILE *bcpl_OUTPUT_fp=(FILE *)0; 15 16 FILE * 17 bcpl_FINDINPUT(char *file) 18 { 19 IF strcmp(file, ".IN") == 0 DO file="/dev/stdin"; 20 RESULTIS fopen(file, "r"); 21 } 22 23 FILE * 24 bcpl_FINDOUTPUT(char *file) 25 { 26 IF strcmp(file, ".OUT") == 0 DO file="/dev/stdout"; 27 IF strcmp(file, ".ERR") == 0 DO file="/dev/stderr"; 28 RESULTIS fopen(file, "w"); 29 } 30 31 // EMAS's READN() gobbles up the following character 32 // and deposits it in a global variable TERMINATOR. So we do the same. 33 34 // KRC only needs positive numbers, and an initial digit is guaranteed, 35 WORD bcpl_READN() 36 { WORD D = 0; 37 int CH = RDCH(); 38 WHILE isdigit(CH) DO { 39 D=D*10+(CH-'0'); 40 CH=RDCH(); 41 } 42 TERMINATOR=CH; 43 RESULTIS D; 44 } 45 46 // The character that has been UNRDCH-ed. -1 means none are pending. 47 static int UNREADCH=-1; 48 49 // The standard function for RDCH(c) 50 int bcpl_RDCH() 51 { 52 IF UNREADCH>=0 DO { 53 int CH=UNREADCH; 54 UNREADCH=-1; 55 RESULTIS CH; 56 } 57 RESULTIS getc(bcpl_INPUT); 58 } 59 60 // A version of RDCH that echoes what it reads 61 int echo_RDCH() 62 { 63 int CH; 64 IF UNREADCH>=0 DO { 65 CH=UNREADCH; 66 UNREADCH=-1; 67 RESULTIS CH; 68 } 69 CH=getc(bcpl_INPUT); 70 WRCH(CH); 71 RESULTIS CH; 72 } 73 74 int bcpl_UNRDCH(int c) 75 { 76 return(UNREADCH=c & 0xff); 77 } 78 79 // The standard function for WRCH(c) 80 void bcpl_WRCH(WORD C) 81 { 82 putc(C, bcpl_OUTPUT); 83 } 84 85 // _RDCH and _WRCH are the function pointers used to perform 86 // RDCH() and WRCH() and may be modified to attain special effects. 87 // Normally in BCPL you would say "WRCH=WHATEVER" 88 // but in C, WRCH and WRCH() would conflict so 89 // say _WRCH=WHATEVER to change it, 90 91 int (*_RDCH)() = bcpl_RDCH; 92 int (*_UNRDCH)(int) = bcpl_UNRDCH; 93 void (*_WRCH)(WORD C) = bcpl_WRCH; 94 95 // Other output functions must go through WRCH so that 96 // callers may redirect it to some other function. 97 void 98 bcpl_WRITES(char *s) { while (*s) WRCH(*s++); } 99 100 // Helper function writes positive integers 101 static void 102 bcpl_WRITEP(WORD n) { 103 if (n/10) bcpl_WRITEP(n/10); 104 WRCH(n%10 + '0'); 105 } 106 107 void 108 bcpl_WRITEN(WORD n) { 109 if (n<0) { WRCH('-'); n=-n; } 110 bcpl_WRITEP(n); 111 }