diff --git a/README b/README index 885f14e388..242683e25f 100644 --- a/README +++ b/README @@ -160,10 +160,6 @@ There are some things you should be aware of. - The ACK uses its own .o format. You won't be able to mix the ACK's object files and another compiler's. -- When compiling together multiple B source files, you need to do some extra - work to initialise them properly otherwise your program will crash on - startup; see the ack(1) and abmodules(1) man pages. - - The distribution contains *everything*, including the weird, ancient, archaic stuff that doesn't work any more and never will, such as the int EM interpreter and the assembler-linkers. Only some of it builds. Look for diff --git a/build.lua b/build.lua index 418bc7dc0e..eca4e649e8 100644 --- a/build.lua +++ b/build.lua @@ -43,7 +43,6 @@ installable { "lang/cem/cemcom.ansi+pkg", "lang/m2/comp+pkg", "lang/pc/comp+pkg", - "lang/b/compiler+pkg", "util/ack+pkg", "util/amisc+pkg", "util/arch+pkg", diff --git a/examples/build.lua b/examples/build.lua index d30f3745cb..4e4aa92777 100644 --- a/examples/build.lua +++ b/examples/build.lua @@ -9,7 +9,6 @@ local softfp = { } local sourcefiles = filenamesof( - "./hilo.b", "./hilo.bas", "./hilo.c", "./hilo.mod", diff --git a/examples/hilo.b b/examples/hilo.b deleted file mode 100644 index 818d1fb12a..0000000000 --- a/examples/hilo.b +++ /dev/null @@ -1,108 +0,0 @@ -# - -buffer[6]; -PlayerName[6]; - -/* Taken intact from the B reference manual. */ -strcopy(sl ,s2) -{ - auto i; - - i = 0; - while (lchar(sl, i, char(s2, i)) != '*e') - i++; -} - -reads() -{ - extrn buffer; - - putstr("> "); - flush(); - getstr(buffer); -} - -atoi(s) -{ - auto value, sign, i, c; - - i = 0; - if (char(s, i) == '-') - { - sign = -1; - i++; - } - else - sign = 1; - - value = 0; - while ((c = char(s, i++)) != '*e') - value = value*10 + (c - '0'); - - return(value * sign); -} - -rand() -{ - /* Genuinely random; retrieved from random.org */ - return(57); -} - -game() -{ - extrn buffer; - auto Number, Attempts; - auto guess; - - printf("See if you can guess my number.*n"); - - Number = rand() % 100; - Attempts = 1; - - while (1) - { - reads(); - guess = atoi(buffer); - - if (guess == Number) - { - printf("*nYou got it right in only %d %s!*n", Attempts, - (Attempts == 1) ? "go" : "goes"); - return; - } - - if (guess < Number) - printf("*nTry a bit higher.*n"); - if (guess > Number) - printf("*nTry a bit lower.*n"); - Attempts++; - } -} - -main() -{ - extrn buffer, PlayerName; - - printf("*nHi there! I'm written in B. Before we start, what is your name?*n"); - reads(); - strcopy(PlayerName, buffer); - printf("*nHello, %s! ", PlayerName); - - while (1) - { - game(); - printf("*nWould you like another go?*n"); - reads(); - - if ((char(buffer, 0) == 'n') | (char(buffer, 0) == 'N')) - { - printf("*nThanks for playing --- goodbye!*n"); - break; - } - - printf("*nExcellent! "); - } - - return(0); -} - diff --git a/lang/b/LICENSE b/lang/b/LICENSE deleted file mode 100644 index db5ca3b4b3..0000000000 --- a/lang/b/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013-2016 aap - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/lang/b/README.md b/lang/b/README.md deleted file mode 100644 index d2ab5faf4b..0000000000 --- a/lang/b/README.md +++ /dev/null @@ -1,53 +0,0 @@ -A B Compiler -============ - -abc is a compiler for the [B Programming Language](http://en.wikipedia.org/wiki/B_(programming_language)) that targets x86\_32 processors. It is currently tested under Linux but should work (or at least be easily ported) to other UNIX-like systems. The code is based on [an early C compiler (last1120c)](http://www.cs.bell-labs.com/who/dmr/primevalC.html) by Dennis Ritchie. - -Documentation -------------- - -* [The Programming Language B](http://9p.io/cm/cs/who/dmr/bintro.html) - -* [B Reference by Ken Thompson](http://9p.io/cm/cs/who/dmr/kbman.html) describes a presumably earlier variant of B, which is slightly different from the one described above. The compiler cannot understand it, but I plan to implement a compatibility mode (the differences are minor). - -Implementation --------------- - -Since B was first implemented for machines with word addressing, some hacking was required to make it work on the byte addressed x86. Addresses filled in by the linker are always byte addresses, so pointers to these addresses are collectively stored at the end of the .data section and are then converted to word addresses at runtime, before main() is called. - -The generated assembly is *very* inefficient, not even constant expressions are reduced at compile time. Also I/O is currently not buffered. - -How to use ----------- - -The installation requires a little configuration: -'abc' is a frontend for the actual compiler which feels somewhat like gcc (it also handles assembling and linking). Before you can use it, set it's BDIR variable to the directory of the B compiler. -In the Makefile, change the directory of the 'install' rule to wherever you want your 'abc' file to reside. -Then type - - make install libs - -which compiles the compiler 'b', installs the 'abc' frontend and compiles the B runtime and library (brt.o and lib.o). - -To compile and link a B program, simply type - - abc -o outfile file1.b [file2.b ...] - -If you want to compile and assemble only: - - abc -c file1.b [file2.b ...] - -or generate only the assembly: - - abc -S file1.b [file2.b ...] - -Examples of B programs are in the 'examples' directory, they are mostly from Brian Kernighan's tutorial. - -Bugs ----- - -Since command line parameters aren't passed word-aligned, B can't handle them easily. brt.s copies the strings to another location and aligns them, the space is not dynamically allocated however and only 256 bytes are available by default. - -The library is incomplete but has some of the most important functions. - -I have only tested the compiler on an x86\_64 gentoo system. diff --git a/lang/b/compiler/b.h b/lang/b/compiler/b.h deleted file mode 100644 index ab66d0b29d..0000000000 --- a/lang/b/compiler/b.h +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "astring.h" - -#define NCPS 8 /* chars per symbol */ -#define HSHSIZ 400 /* hash table size */ -#define SWSIZ 230 /* switch table size */ -#define CMSIZ 40 /* symbol stack size */ -#define SSIZE 20 /* operator and precedence stack size */ -#define OSSIZ 300*8 /* space for expression tree */ - -#define EOS 04 /* end of string marker */ - -/* - * Holds a B symbol. - * class is one of the storage classes below. - * offset is used depending on class. - */ -struct hshtab { - int class; - int offset; - int dim; - struct hshtab *next; - char name[NCPS+1]; -}; - -struct tnode { - int op; - int value; - struct tnode *tr1; - struct tnode *tr2; -}; - -struct swtab { - int swlab; - int swval; -}; - -extern int wordsize; -extern const char* modulename; -extern int paramsize; -extern struct hshtab hshtab[HSHSIZ]; -extern int hshused; -extern int ateof; -extern int peekc; -extern const char* ctab; -extern struct hshtab *bsym; -extern struct hshtab *paraml, *parame; -extern int cval; -extern int isn; -extern char symbuf[NCPS+1]; -extern FILE *sbufp; -extern int stack; -extern struct tnode **cp; -extern int *space; -extern int ospace[OSSIZ]; -extern int retlab; -extern int nerror; -extern struct swtab swtab[SWSIZ]; -extern struct swtab *swp; -extern int deflab; -extern int contlab; -extern int brklab; - -extern int opdope[]; -extern int line; -extern int peeksym, peeksym2; - -extern void error(char *s, ...); -extern void printtoken(int tok, FILE *out); -extern struct tnode * block(int op, int value, struct tnode *tr1, struct tnode *tr2); -extern void rcexpr(struct tnode *tr); -extern void cbranch(struct tnode *t, int lab); -extern void jump(int lab); -extern void fnlabel(int l); -extern void tonativeaddr(void); -extern void fromnativeaddr(void); -extern char* manglename(char* name, char prefix); - -#define EOFC 0 -#define SEMI 1 -#define LBRACE 2 -#define RBRACE 3 -#define LBRACK 4 -#define RBRACK 5 -#define LPARN 6 -#define RPARN 7 -#define COLON 8 -#define COMMA 9 -#define HASH 10 - -#define MCALL 15 -#define CALL 16 -#define DECBEF 17 -#define INCBEF 18 -#define DECAFT 19 -#define INCAFT 20 -#define EXCLA 21 -#define NEG 22 -#define AMPER 23 -#define STAR 24 -#define QUEST 25 -#define NOT 26 - -#define PLUS 30 -#define MINUS 31 -#define MOD 32 -#define TIMES 33 -#define DIVIDE 34 -#define OR 35 -#define AND 36 -#define LSHIFT 37 -#define RSHIFT 38 -#define EQUAL 39 -#define NEQUAL 40 -#define LESSEQ 41 -#define LESS 42 -#define GREATEQ 43 -#define GREAT 44 -#define EOR 45 - -#define ASSIGN 49 -#define ASPLUS 50 -#define ASMINUS 51 -#define ASMOD 52 -#define ASTIMES 53 -#define ASDIV 54 -#define ASOR 55 -#define ASAND 56 -#define ASLSH 57 -#define ASRSH 58 -#define ASEQUAL 59 -#define ASNEQL 60 -#define ASLEQ 61 -#define ASLESS 62 -#define ASGTQ 63 -#define ASGREAT 64 -#define ASEOR 65 - -#define CON 70 -#define STRING 71 -#define NAME 72 -#define KEYW 73 - -#define SQUOTE 121 -#define DQUOTE 122 -#define NEWLN 123 -#define SPACE 124 -#define LETTER 125 -#define DIGIT 126 -#define UNKN 127 - -#define SEOF 200 - -/* storage classes */ -#define AUTO 1 -#define EXTERN 2 -#define INTERN 3 -#define ARG 4 -#define KEYWF 5 - -/* keywords */ -#define CASE 3 -#define IF 4 -#define ELSE 5 -#define WHILE 6 -#define SWITCH 7 -#define GOTO 8 -#define RETURN 9 -#define DEFAULT 10 -#define BREAK 11 - diff --git a/lang/b/compiler/b0.c b/lang/b/compiler/b0.c deleted file mode 100644 index 1d96857fd3..0000000000 --- a/lang/b/compiler/b0.c +++ /dev/null @@ -1,1422 +0,0 @@ -#include "b.h" - -void extdef(void); -struct hshtab * lookup(void); -void blkhed(void); -void blkend(void); -void statement(int d); -struct tnode * tree(void); -void errflush(int o); - -int line = 1; -int peeksym = -1, peeksym2 = -1;; -int contlab = -1; -int brklab = -1; - -int wordsize = 4; -const char* modulename = "bmodule_main"; -int bsymb_part; -int code_part; -int string_part; - -int paramsize; -struct hshtab hshtab[HSHSIZ]; -int hshused; -int ateof; -int peekc; -const char* ctab; -struct hshtab *bsym; -struct hshtab *paraml, *parame; -int cval; -int isn; -char symbuf[NCPS+1]; -FILE *sbufp; -int stack; -struct tnode **cp; -int *space; -int ospace[OSSIZ]; -int retlab; -int nerror; -struct swtab swtab[SWSIZ]; -struct swtab *swp; -int deflab; -int contlab; -int brklab; - -int opdope[]; -int line; -int peeksym, peeksym2; - - -void -init(char *s, int val) -{ - char *sp; - struct hshtab *np; - - sp = symbuf; - while (sp < symbuf+NCPS+1) - if ((*sp++ = *s++) == '\0') - s--; - np = lookup(); - np->class = KEYWF; - np->offset = val; -} - -static void -usage(void) -{ - error("Usage: em_b [-w wordsize] [-B modulename] [-i inputfile] [-o outputfile]"); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - - for (;;) { - int opt = getopt(argc, argv, "w:B:i:o:"); - if (opt == -1) - break; - - switch (opt) { - case 'w': - wordsize = atoi(optarg); - break; - - case 'B': - modulename = aprintf("bmodule_%s", optarg); - break; - - case 'i': - if (freopen(optarg, "r", stdin) == NULL) { - error("Can't find %s", optarg); - exit(1); - } - break; - - case 'o': - if (freopen(optarg, "w", stdout) == NULL) { - error("Can't create %s", optarg); - exit(1); - } - break; - - default: - usage(); - } - } - if (optind < argc) - usage(); - - init("auto", AUTO); - init("extrn", EXTERN); - init("case", CASE); - init("if", IF); - init("else", ELSE); - init("while", WHILE); - init("switch", SWITCH); - init("goto", GOTO); - init("return", RETURN); - init("default", DEFAULT); - init("break", BREAK); - - C_init(wordsize, wordsize); - C_open(NULL); - C_magic(); - C_ms_emx(wordsize, wordsize); - bsymb_part = 0; - string_part = 0; - code_part = C_getid(); - C_beginpart(code_part); - while (!ateof) { - extdef(); - blkend(); - } - C_endpart(code_part); - C_insertpart(code_part); - - if (string_part) - C_insertpart(string_part); - - C_exa_dnam((char*) modulename); - C_df_dnam((char*) modulename); - if (bsymb_part) - C_insertpart(bsymb_part); - C_rom_cst(0); - - C_close(); - - return nerror != 0; -} - -/* - * Lexer - */ - -int -spnextchar(void) -{ - int c; - - if ((c = peekc) == 0) - c = getchar(); - if (c == '\t') - c = ' '; - else if (c == '\n') { - c = ' '; - line++; - } - peekc = c; - return c; -} - -int -nextchar(void) -{ - while (spnextchar() == ' ') - peekc = 0; - return peekc; -} - -int -subseq(int c, int a, int b) -{ - if (spnextchar() != c) - return a; - peekc = 0; - return b; -} - -/* Only decimal and octal bases, could extend */ -int -getnum(void) -{ - int base; - int c; - - base = 10; - cval = 0; - if ((c=spnextchar()) == '0') - base = 8; - for (; ctab[c] == DIGIT; c = getchar()) - cval = cval*base + c-'0'; - peekc = c; - return CON; -} - -int -mapch(char c) -{ - int a; - - if ((a=getchar()) == c) - return -1; - switch (a) { - - case '\n': - case '\0': - error("Nonterminated string"); - peekc = a; - return -1; - - case '*': - switch (a=getchar()) { - - case 't': - return('\t'); - - case 'n': - return('\n'); - - case '0': - return('\0'); - - case '(': - return('{'); - - case ')': - return('}'); - - case 'e': - return(EOS); - - case '\n': - line++; - return('\n'); - } - } - return a; -} - -int -getcc(void) -{ - char *cp; - int c, cc; - - cval = 0; - cc = 0; - cp = (char*) &cval; - while ((c = mapch('\'')) >= 0) - if (cc++ < wordsize) - *cp++ = c; - if (cc > wordsize) - error("Long character constant"); - return CON; -} - -int -getstr(void) -{ - int c; - int i; - char b; - int partid; - - partid = C_getid(); - C_beginpart(partid); - if (string_part) - C_insertpart(string_part); - - cval = isn++; - C_df_dlb(cval); - for (i = 1; (c = mapch('"')) >= 0; i++) { - b = c; - C_con_scon(&b, 1); - } - - b = 04; - C_con_scon(&b, 1); - - b = 0; - while ((i++%4) != 0) - C_con_scon(&b, 1); - - C_endpart(partid); - string_part = partid; - - return STRING; -} - -struct hshtab * -lookup(void) -{ - int i; - char *sp, *np; - struct hshtab *rp; - - i = 0; - sp = symbuf; - while (sp < symbuf+NCPS) - i += *sp++&0177; - rp = &hshtab[i%HSHSIZ]; - while (*(np = rp->name)) { - for (sp=symbuf; sp < symbuf+NCPS;) - if (*np++ != *sp++) - goto no; - return rp; - no: - if (++rp >= &hshtab[HSHSIZ]) - rp = hshtab; - } - if (++hshused > HSHSIZ) { - error("Symbol table overflow"); - exit(1); - } - rp->class = 0; - rp->offset = 0; - rp->dim = 0; - sp = symbuf; - for (np = rp->name; sp < symbuf+NCPS+1;) - *np++ = *sp++; - return rp; -} - -/* - * Symbol peeking with one peeksym doesn't work if an ASSIGN is only peeked, - * since it itself peeks a symbol, which is then overwritten. - */ - -/* Note: does not push bsyms !! */ -int -pushsym(int sym) -{ - if (peeksym < 0) - peeksym = sym; - else if (peeksym2 < 0) { - peeksym2 = peeksym; - peeksym = sym; - } else - error("Cannot push more than two symbols\n"); - return sym; -} - -int -symbol(void) -{ - int c; - char *sp; - - if (peeksym >= 0) { - c = peeksym; - peeksym = peeksym2; - peeksym2 = -1; - return c; - } - if (peekc) { - c = peekc; - peekc = 0; - } else - if (ateof) - return EOFC; - else - c = getchar(); - if (c==EOF) { - ateof++; - return(EOFC); - } - -loop: - switch (ctab[c]) { - - case NEWLN: - line++; - /* fall through */ - case SPACE: - c = getchar(); - goto loop; - - case HASH: - /* # is invalid in B; but we handle it out of convenience so that we can read - * in input files that have been run through the C preprocessor. Ideally we - * should only recognise it when it's the first character in a line, but as - * it's not used anywhere else we can get away with recognising it anywhere. - */ - - while ((c = getchar()) == ' ') - ; - - peekc = c; - getnum(); - line = cval; - - while ((c = getchar()) != '\n') - ; - - goto loop; - - case PLUS: - return subseq(c,PLUS,INCBEF); - - case MINUS: - return subseq(c,MINUS,DECBEF); - - case LESS: - if (subseq(c,0,1)) - return LSHIFT; - return subseq('=', LESS, LESSEQ); - - case GREAT: - if (subseq(c,0,1)) - return RSHIFT; - return subseq('=', GREAT, GREATEQ); - - case ASSIGN: - if (subseq(' ',0,1)) - return ASSIGN; - /* avoid peeking a name, which could overwrite - * an already set bsym. */ - if (ctab[peekc = spnextchar()] == LETTER) - return ASSIGN; - c = symbol(); - if (PLUS <= c && c <= EOR) - return c + ASPLUS-PLUS; - if (c == ASSIGN) - return EQUAL; - pushsym(c); - return ASSIGN; - - case EXCLA: - return subseq('=',EXCLA,NEQUAL); - - case DIVIDE: - if (subseq('*',1,0)) - return DIVIDE; - while ((c = spnextchar()) != EOFC) { - peekc = 0; - if (c == '*') { - if (spnextchar() == '/') { - peekc = 0; - c = getchar(); - goto loop; - } - } - } - ateof++; - error("Nonterminated comment"); - return EOFC; - - case DIGIT: - peekc = c; - return getnum(); - - case SQUOTE: - return(getcc()); - - case DQUOTE: - return(getstr()); - - case LETTER: - sp = symbuf; - while (ctab[c] == LETTER || ctab[c] == DIGIT) { - if (sp < symbuf+NCPS) - *sp++ = c; - c = getchar(); - } - while (sp < symbuf+NCPS+1) - *sp++ = '\0'; - peekc = c; - bsym = lookup(); - if (bsym->class == KEYWF) { - cval = bsym->offset; - return KEYW; - } - return NAME; - - case UNKN: - error("Unknown character"); - c = getchar(); - goto loop; - } - return (ctab[c]); -} - -/* - * Declarations and Definitions - */ - -/* Declares a list of names to be of storage class "kw". */ -void -declare(int kw) -{ - int o; - - while ((o = symbol()) == NAME) { - if (bsym->class) - error("%s redeclared", bsym->name); - bsym->class = kw; - while ((o = symbol()) == LBRACK) { - if ((o = symbol()) == CON) { - if (bsym->dim) - error("Bad vector"); - bsym->dim = cval + 1; - o = symbol(); - } - if (o != RBRACK) - goto syntax; - } - if (kw == ARG) { - bsym->next = NULL; - if (!paraml) - paraml = bsym; - else - parame->next = bsym; - parame = bsym; - } - if (o != COMMA) - break; - } - if ((o == SEMI && kw != ARG) || (o == RPARN && kw == ARG)) - return; -syntax: - error("Declaration syntax"); - errflush(o); -} - -void -declist(void) -{ - int o; - - while ((o = symbol()) == KEYW && (cval == AUTO || cval == EXTERN)) - declare(cval); - pushsym(o); -} - -void -function(void) -{ - declare(ARG); - statement(1); - C_ret(0); - C_end(paramsize); -} - -void -global(char *s) -{ - C_exa_dnam(manglename(s, 'b')); -} - -void -bsymb(char *s) -{ - int newpart = C_getid(); - C_beginpart(newpart); - if (bsymb_part != 0) - C_insertpart(bsymb_part); - C_rom_dlb(isn, 0); - C_endpart(newpart); - - bsymb_part = newpart; - C_df_dlb(isn++); -} - -void -extdef(void) -{ - int o, dim, i; - char *bs; - char *ms; - int neg; - - if ((o = symbol()) == EOFC || o == SEMI) - return; - if (o != NAME) - goto syntax; - bs = bsym->name; - i = dim = 0; - neg = 0; - switch(o = symbol()) { - - case SEMI: - global(bs); - C_df_dnam(manglename(bs, 'b')); - C_bss_cst(wordsize, 0, 1); - goto done; - - /* init */ - case CON: - case STRING: - case MINUS: - global(bs); - if (o == STRING) - bsymb(bs); - else if (o == MINUS) { - o = symbol(); - if (o != CON) - goto syntax; - cval = -cval; - } - C_df_dnam(manglename(bs, 'b')); - pushsym(o); - goto init; - - /* vector */ - case LBRACK: - if ((o=symbol()) == CON) { - dim = cval + 1; - o=symbol(); - } - if (o != RBRACK) - goto syntax; - global(bs); - if ((o=symbol()) == SEMI) { - bsymb(bs); - C_df_dnam(manglename(bs, 'b')); - C_con_dlb(isn, 0); - C_df_dlb(isn++); - C_bss_cst(wordsize*dim, 0, 1); - goto done; - } - bsymb(bs); - C_df_dnam(manglename(bs, 'b')); - C_con_dlb(isn, 0); - C_df_dlb(isn++); - pushsym(o); - - init: - do { - if ((o=symbol()) != CON && o != STRING && o != NAME) - goto syntax; - if (o == NAME) { - bsymb(NULL); - C_con_dnam(manglename(bsym->name, 'b'), 0); - } else { - if (o == STRING) { - bsymb(NULL); - C_con_dlb(cval, 0); - } else - C_con_cst(cval); - } - i++; - } while ((o=symbol()) == COMMA); - dim = (i > dim) ? i : dim; - if (i == 0) - C_bss_cst((dim-i)*wordsize, 0, 1); - else { - while (dim -i) { - C_con_cst(0); - i++; - } - } - if (o == SEMI) - goto done; - goto syntax; - - /* function */ - case LPARN: - global(bs); - ms = manglename(bs, 'b'); - bsymb(ms); - C_df_dnam(ms); - ms = manglename(bs, 'i'); - C_con_pnam(ms); - C_inp(ms); - C_pro_narg(ms); - function(); - done: - return; - - case EOFC: - return; - } -syntax: - error("External definition syntax"); - printtoken(o, stderr); - errflush(o); - statement(0); -} - -void -blkhed(void) -{ - int al, pl; - struct hshtab *bs; - - declist(); - stack = al = -wordsize; - pl = 0; /* EM parameters start at offset 0. */ - while (paraml) { - paraml = (bs = paraml)->next; - bs->offset = pl; - pl += wordsize; - } - for (bs = hshtab; bs < &hshtab[HSHSIZ]; bs++) - if (bs->name[0]) { - if (bs->class == AUTO) { - bs->offset = al; - if (bs->dim) { - al -= bs->dim*wordsize; - C_lal(al); - al -= wordsize; - fromnativeaddr(); - C_stl(al); - bs->offset = al; - } - al -= wordsize; - } else if (bs->class == ARG) - bs->class = AUTO; - } - paramsize = -al - wordsize; -} - -void -blkend(void) -{ - struct hshtab *np; - - for (np = hshtab; np < &hshtab[HSHSIZ]; np++) - if (np->class != KEYWF) { - np->name[0] = '\0'; - hshused--; - } -} - -/* - * Statements and Expressions - */ - -struct tnode * -pexpr(void) -{ - struct tnode *t; - int o; - - if ((o = symbol()) != LPARN) - goto syntax; - t = tree(); - if ((o = symbol()) != RPARN) - goto syntax; - return t; -syntax: - error("Statement syntax"); - errflush(o); - return NULL; -} - -void -fnlabel(int l) -{ - C_ilb(l); -} - -/* Jump to "lab", if the expression "t" evaluated to 0. */ -void -cbranch(struct tnode *t, int lab) -{ - rcexpr(t); - C_zeq(lab); -} - -void -jump(int lab) -{ - C_bra(lab); -} - -void -pswitch(void) -{ - struct swtab *sswp; - int dl, swlab; - - if (swp == NULL) - swp = swtab; - sswp = swp; - swlab = isn++; - C_lae_dlb(swlab, 0); - C_csb(wordsize); - - dl = deflab; - deflab = 0; - statement(0); - if (!deflab) - deflab = brklab; - - C_df_dlb(swlab); - C_rom_ilb(deflab); - C_rom_cst(swp - sswp); - - while (swp > sswp && swp > swtab) { - --swp; - C_rom_cst(swp->swval); - C_rom_ilb(swp->swlab); - } - - C_df_ilb(brklab); - - deflab = dl; - swp = sswp; -} - -void -statement(int d) -{ - int o, o1, o2; - -stmt: - if ((o = symbol()) == LBRACE) { - if (d) - blkhed(); - while (!ateof) { - if ((o = symbol()) == RBRACE) - goto bend; - pushsym(o); - statement(0); - } - error("Missing '}'"); - bend: - return; - } else { - pushsym(o); - if (d) - blkhed(); - } - - switch (o = symbol()) { - - case EOFC: - error("Unexpected EOF"); - - case SEMI: - case RBRACE: - return; - - case KEYW: - switch (cval) { - case GOTO: - if ((o = symbol()) != NAME) - goto syntax; - if (bsym->offset == 0) - bsym->offset = isn++; - jump(bsym->offset); - goto semi; - - case RETURN: - if (pushsym(symbol()) == LPARN) { - rcexpr(pexpr()); - C_ret(wordsize); - } else { - C_ret(0); - } - goto semi; - - case IF: - cbranch(pexpr(), o1=isn++); - statement(0); - if ((o = symbol()) == KEYW && cval == ELSE) { - jump(o2 = isn++); - fnlabel(o1); - statement(0); - fnlabel(o2); - return; - } - pushsym(o); - fnlabel(o1); - return; - - case WHILE: - o1 = contlab; - o2 = brklab; - fnlabel(contlab = isn++); - cbranch(pexpr(), brklab=isn++); - statement(0); - jump(contlab); - fnlabel(brklab); - contlab = o1; - brklab = o2; - return; - - case BREAK: - if (brklab < 0) - error("Nothing to break from"); - jump(brklab); - goto semi; - - /* Not part of B, but very easy to implement */ -/* - case CONTINUE: - if (contlab < 0) - error("Nothing to continue"); - jump(contlab); - goto semi; -*/ - - case SWITCH: - o1 = brklab; - brklab = isn++; - rcexpr(pexpr()); -/* rcexpr(tree()); */ - pswitch(); - brklab = o1; - return; - - case CASE: - if ((o = symbol()) != CON) - goto syntax; - if ((o = symbol()) != COLON) - goto syntax; - if (swp == NULL) { - error("Case not in switch"); - goto stmt; - } - if (swp >= swtab+SWSIZ) - error("Switch table overflow"); - else { - swp->swlab = isn; - (swp++)->swval = cval; - fnlabel(isn++); - } - goto stmt; - - case DEFAULT: - if (swp == NULL) - error("Default not in switch"); - if ((o = symbol()) != COLON) - goto syntax; - deflab = isn++; - fnlabel(deflab); - goto stmt; - } - - error("Unknown keyword"); - goto syntax; - - case NAME: - if (peekc == ':') { - peekc = 0; - if (bsym->class) { - error("Redefinition"); - goto stmt; - } - bsym->class = INTERN; - if (bsym->offset == 0) - bsym->offset = isn++; - fnlabel(bsym->offset); - goto stmt; - } - } - pushsym(o); - rcexpr(tree()); - C_asp(wordsize); - goto semi; - -semi: - if ((o = symbol()) != SEMI) - goto syntax; - return; - -syntax: - error("Statement syntax"); - errflush(o); - goto stmt; -} - -struct tnode * -block(int op, int value, struct tnode *tr1, struct tnode *tr2) -{ - struct tnode t; - int n; - int *p, *ap; - - p = space; - t.op = op; - t.value = value; - t.tr1 = tr1; - t.tr2 = tr2; - ap = (int*) &t; - n = (sizeof(struct tnode)+sizeof(int)-1) & ~sizeof(int); - if (space+n >= &ospace[OSSIZ]) { - error("Expression overflow 1"); - exit(1); - } - while (n--) - *space++ = *ap++; - return (struct tnode *) p; -} - -void -chklval(struct tnode *p) -{ - if (p->op != NAME && p->op != STAR) - error("Lvalue required"); -} - -void -build(int op) -{ - struct tnode *p1, *p2; - int dope; - - /* a[i] -> *(a+i) */ - if (op == LBRACK) { - build(PLUS); - op = STAR; - } - dope = opdope[op]; - if (dope&01) - p2 = *--cp; - p1 = *--cp; - switch (op) { - case QUEST: - if (p2->op != COLON) - error("Illegal conditional"); - break; - - case AMPER: - if (p1->op == STAR) { - *cp++ = p1->tr1; - return; - } - if (p1->op == NAME) { - *cp++ = block(op,0,p1,NULL); - return; - } - error("Illegal lvalue"); - } - if (dope&02) - chklval(p1); - if (dope&01) - *cp++ = block(op,0,p1,p2); - else - *cp++ = block(op,0,p1,NULL); -} - -struct tnode * -tree(void) -{ - struct tnode *cmst[CMSIZ]; - int opst[SSIZE], prst[SSIZE]; - int *op, *pp; - int andflg; - int o, os; - int p, ps; - - space = ospace; - op = opst; - pp = prst; - cp = cmst; - *op = SEOF; - *pp = 06; - andflg = 0; - -advanc: - switch (o=symbol()) { - case NAME: - if (pushsym(symbol()) == LPARN) { /* function */ - if (bsym->class == 0) - bsym->class = EXTERN; - } else if (bsym->class == 0) { - error("%s undefined", bsym->name); - bsym->class = EXTERN; - } - *cp++ = block(NAME,0,(struct tnode *)bsym,NULL); - goto tand; - - case STRING: - *cp++ = block(STRING,cval,NULL,NULL); - goto tand; - - case CON: - caseCON: - *cp++ = block(CON,cval,NULL,NULL); - goto tand; - -tand: - if (cp >= &cmst[CMSIZ]) { - error("Expression overflow 2"); - exit(1); - } - if (andflg) - goto syntax; - andflg = 1; - goto advanc; - - case DECBEF: - case INCBEF: - if (andflg) - o += 2; - goto oponst; - - case EXCLA: - case NOT: - if (andflg) - goto syntax; - goto oponst; - - case MINUS: - if (!andflg) { - if (pushsym(symbol()) == CON) { - symbol(); - cval = -cval; - goto caseCON; - } - o = NEG; - } - andflg = 0; - goto oponst; - - case AND: - case TIMES: - if (andflg) - andflg = 0; - else - if (o == AND) - o = AMPER; - else - o = STAR; - goto oponst; - - case LPARN: - if (andflg) { - o = symbol(); - if (o == RPARN) - o = MCALL; - else { - pushsym(o); - o = CALL; - andflg = 0; - } - } - goto oponst; - - case RPARN: - case RBRACK: - if (!andflg) - goto syntax; - goto oponst; - } - - if (!andflg) - goto syntax; - andflg = 0; - -oponst: - p = (opdope[o]>>9) & 077; -opon1: - ps = *pp; - if (p > ps || (p == ps && (opdope[o]&0200))) { /* right-assoc */ - switch (o) { - case LPARN: - case LBRACK: - case CALL: - p = 04; - } - if (op >= &opst[SSIZE]) { - error("Expression overflow 3"); - exit(1); - } - *++op = o; - *++pp = p; - goto advanc; - } - --pp; - switch (os = *op--) { - case SEOF: - pushsym(o); - return(*--cp); - - case CALL: - if (o != RPARN) - goto syntax; - build(os); - goto advanc; - - case MCALL: - *cp++ = NULL; - os = CALL; - goto fbuild; - - case LPARN: - if (o != RPARN) - goto syntax; - goto advanc; - - case LBRACK: - if (o != RBRACK) - goto syntax; - build(LBRACK); - goto advanc; - - } -fbuild: - build(os); - goto opon1; -syntax: - error("Expression syntax"); - errflush(o); - return NULL; -} - -void -error(char *s, ...) -{ - va_list args; - - va_start(args, s); - nerror++; - fprintf(stderr, "%d: ", line); - vfprintf(stderr, s, args); - putc('\n', stderr); - va_end(args); -} - -void -errflush(int o) -{ - while (o > RBRACE) /* ; { } */ - o = symbol(); - pushsym(o); -} - -/* - * 000001 binary - * 000002 need lvalue - * 000004 relational - * 000010 assignment - * 000100 commutative - * 000200 right-assoc - * 0XX000 precedence - */ -int opdope[] = { - 000000, /* EOFC */ - 000000, /* ; */ - 000000, /* { */ - 000000, /* } */ - 036000, /* [ */ - 002000, /* ] */ - 036000, /* ( */ - 002000, /* ) */ - 014201, /* : */ - 007001, /* , */ - 000000, /* 10 */ - 000000, /* 11 */ - 000000, /* 12 */ - 000000, /* 13 */ - 000000, /* 14 */ - 036001, /* mcall */ - 036001, /* call */ - 034202, /* ++a */ - 034202, /* a++ */ - 034202, /* --a */ - 034202, /* a-- */ - 034200, /* !un */ - 034200, /* -un */ - 034200, /* &un */ - 034200, /* *un */ - 014201, /* ? */ - 034200, /* ~un */ - 000000, /* 27 */ - 000000, /* 28 */ - 000000, /* 29 */ - 030101, /* + */ - 030001, /* - */ - 032001, /* % */ - 032101, /* * */ - 032001, /* / */ - 016101, /* | */ - 020101, /* & */ - 026001, /* << */ - 026001, /* >> */ - 022105, /* == */ - 022105, /* != */ - 024005, /* <= */ - 024005, /* < */ - 024005, /* >= */ - 024005, /* > */ - 017005, /* ^ */ - 000000, /* 46 */ - 000000, /* 47 */ - 000000, /* 48 */ - 012013, /* = */ - 012213, /* =+ */ - 012213, /* =- */ - 012213, /* =% */ - 012213, /* =* */ - 012213, /* =/ */ - 012213, /* =| */ - 012213, /* =& */ - 012213, /* =<< */ - 012213, /* =>> */ - 012213, /* === */ - 012213, /* =!= */ - 012213, /* =<= */ - 012213, /* =< */ - 012213, /* =>= */ - 012213, /* => */ - 012213, /* =^ */ - 000000, /* 66 */ - 000000, /* 67 */ - 000000, /* 68 */ - 000000, /* 69 */ - 000000, /* CON */ - 000000, /* STRING */ - 000000 /* NAME */ -}; - -const char ctaba[129] = { - EOFC, /* -1 */ - EOFC, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - LETTER, SPACE, NEWLN, SPACE, SPACE, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - SPACE, EXCLA, DQUOTE, HASH, UNKN, MOD, AND, SQUOTE, - LPARN, RPARN, TIMES, PLUS, COMMA, MINUS, UNKN, DIVIDE, - DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, - DIGIT, DIGIT, COLON, SEMI, LESS, ASSIGN, GREAT, QUEST, - UNKN, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LBRACK, UNKN, RBRACK, EOR, LETTER, - UNKN, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LBRACE, OR, RBRACE, NOT, UNKN -}; -const char* ctab = &ctaba[1]; /* allows indexing with -1 */ - -/* debug function */ -void printtoken(int tok, FILE *out) -{ - static char *strtab[128]; - strtab[0] = "EOFC"; - strtab[1] = "SEMI"; - strtab[2] = "LBRACE"; - strtab[3] = "RBRACE"; - strtab[4] = "LBRACK"; - strtab[5] = "RBRACK"; - strtab[6] = "LPARN"; - strtab[7] = "RPARN"; - strtab[8] = "COLON"; - strtab[9] = "COMMA"; - strtab[10] = "HASH"; - - strtab[15] = "MCALL"; - strtab[16] = "CALL"; - strtab[17] = "DECBEF"; - strtab[18] = "INCBEF"; - strtab[19] = "DECAFT"; - strtab[20] = "INCAFT"; - strtab[21] = "EXCLA"; - strtab[22] = "NEG"; - strtab[23] = "AMPER"; - strtab[24] = "STAR"; - strtab[25] = "QUEST"; - strtab[26] = "NOT"; - - strtab[30] = "PLUS"; - strtab[31] = "MINUS"; - strtab[32] = "MOD"; - strtab[33] = "TIMES"; - strtab[34] = "DIVIDE"; - strtab[35] = "OR"; - strtab[36] = "AND"; - strtab[37] = "LSHIFT"; - strtab[38] = "RSHIFT"; - strtab[39] = "EQUAL"; - strtab[40] = "NEQUAL"; - strtab[41] = "LESSEQ"; - strtab[42] = "LESS"; - strtab[43] = "GREATEQ"; - strtab[44] = "GREAT"; - strtab[45] = "EOR"; - - strtab[49] = "ASSIGN"; - strtab[50] = "ASPLUS"; - strtab[51] = "ASMINUS"; - strtab[52] = "ASMOD"; - strtab[53] = "ASTIMES"; - strtab[54] = "ASDIV"; - strtab[55] = "ASOR"; - strtab[56] = "ASAND"; - strtab[57] = "ASLSH"; - strtab[58] = "ASRSH"; - strtab[59] = "ASEQUAL"; - strtab[60] = "ASNEQL"; - strtab[61] = "ASLEQ"; - strtab[62] = "ASLESS"; - strtab[63] = "ASGTQ"; - strtab[64] = "ASGREAT"; - strtab[65] = "ASEOR"; - - strtab[70] = "CON"; - strtab[71] = "STRING"; - strtab[72] = "NAME"; - strtab[73] = "KEYW"; - - strtab[127] = "UNKN"; - - if (tok == CON || tok == STRING) { - fprintf(out, "%s(%d) ", strtab[tok], cval); - return; - } - if (tok == NAME) { - fprintf(out, "%s(%s) ", strtab[tok], symbuf); - return; - } - - fprintf(out, "%s ", strtab[tok]); -} - diff --git a/lang/b/compiler/b1.c b/lang/b/compiler/b1.c deleted file mode 100644 index ca5ae55934..0000000000 --- a/lang/b/compiler/b1.c +++ /dev/null @@ -1,403 +0,0 @@ -#include "b.h" - -/* - * Code generation (EM) - */ - -static int -shiftsize(void) -{ - switch (wordsize) { - case 1: return 0; - case 2: return 1; - case 4: return 2; - case 8: return 3; - default: - error("unsupported word size"); - exit(1); - } -} - -void -tonativeaddr(void) -{ - C_loc(shiftsize()); - C_slu(wordsize); -} - -void -fromnativeaddr(void) -{ - C_loc(shiftsize()); - C_sru(wordsize); -} - -char* -manglename(char* name, char prefix) -{ - static char buffer[NCPS+3]; - buffer[0] = prefix; - buffer[1] = '_'; - strcpy(buffer+2, name); - return buffer; -} - -void -binary(struct tnode *tr) -{ - rcexpr(tr->tr1); - rcexpr(tr->tr2); -} - -int -pushargs(struct tnode *tr) -{ - int stk; - - if (tr == NULL) - return 0; - if (tr->op == COMMA) { - rcexpr(tr->tr2); - stk = pushargs(tr->tr1); - return stk+wordsize; - } - rcexpr(tr); - return wordsize; -} - -void -lvalexp(struct tnode *tr) -{ - struct hshtab *bs; - char memloc[64]; - - switch (tr->op) { - - case DECBEF: - case INCBEF: - case DECAFT: - case INCAFT: - if (tr->tr1->op == STAR) { - rcexpr(tr->tr1->tr1); - tonativeaddr(); - - if ((tr->op == DECBEF) || (tr->op == INCBEF)) { - C_dup(wordsize); /* ( addr addr -- ) */ - C_loi(wordsize); /* ( addr val -- ) */ - if (tr->op == DECBEF) - C_dec(); /* ( addr newval -- ) */ - else - C_inc(); /* ( addr newval -- ) */ - C_exg(wordsize); /* ( newval addr -- ) */ - C_dup(wordsize*2); /* ( newval addr newval addr -- ) */ - C_sti(wordsize); /* ( newval addr -- ) */ - C_asp(wordsize); /* ( newval -- ) */ - } else { - C_dup(wordsize); /* ( addr addr -- ) */ - C_loi(wordsize); /* ( addr val -- ) */ - C_dup(wordsize*2); /* ( addr val addr val -- ) */ - if (tr->op == DECAFT) - C_dec(); /* ( addr val addr newval -- ) */ - else - C_inc(); /* ( addr val addr newval -- ) */ - C_exg(wordsize); /* ( addr val newval addr -- ) */ - C_sti(wordsize); /* ( addr val -- ) */ - C_exg(wordsize); /* ( val addr -- ) */ - C_asp(wordsize); /* ( val -- ) */ - } - } else { /* NAME, checked in "build" */ - bs = (struct hshtab *) tr->tr1->tr1; - if (bs->class == EXTERN) { - switch (tr->op) { - case INCBEF: - C_ine_dnam(manglename(bs->name, 'b'), 0); - C_loe_dnam(manglename(bs->name, 'b'), 0); - break; - - case DECBEF: - C_dee_dnam(manglename(bs->name, 'b'), 0); - C_loe_dnam(manglename(bs->name, 'b'), 0); - break; - - case INCAFT: - C_loe_dnam(manglename(bs->name, 'b'), 0); - C_ine_dnam(manglename(bs->name, 'b'), 0); - break; - - case DECAFT: - C_loe_dnam(manglename(bs->name, 'b'), 0); - C_dee_dnam(manglename(bs->name, 'b'), 0); - break; - } - } else if (bs->class == AUTO) { - switch (tr->op) { - case INCBEF: - C_inl(bs->offset); - C_lol(bs->offset); - break; - - case DECBEF: - C_del(bs->offset); - C_lol(bs->offset); - break; - - case INCAFT: - C_lol(bs->offset); - C_inl(bs->offset); - break; - - case DECAFT: - C_lol(bs->offset); - C_del(bs->offset); - break; - } - } else - goto classerror; - } - return; - - case ASSIGN: - rcexpr(tr->tr2); - C_dup(wordsize); - if (tr->tr1->op == STAR) { - rcexpr(tr->tr1->tr1); - tonativeaddr(); - C_sti(wordsize); - } else { /* NAME */ - bs = (struct hshtab *) tr->tr1->tr1; - if (bs->class == EXTERN) { - C_ste_dnam(manglename(bs->name, 'b'), 0); - } else if (bs->class == AUTO) { - C_stl(bs->offset); - } else - goto classerror; - } - return; - - case ASPLUS: - case ASMINUS: - case ASMOD: - case ASTIMES: - case ASDIV: - case ASOR: - case ASAND: - case ASLSH: - case ASRSH: - case ASEQUAL: - case ASNEQL: - case ASLEQ: - case ASLESS: - case ASGTQ: - case ASGREAT: - case ASEOR: - tr->op -= ASPLUS-PLUS; - rcexpr(block(ASSIGN,0,tr->tr1,tr)); - return; - } - -classerror: - error("Storage class"); -} - -void -rcexpr(struct tnode *tr) -{ - int o1, o2; - int stk; - struct hshtab *bs; - - if (tr == NULL) - return; - - if (opdope[tr->op]&02) { - lvalexp(tr); - return; - } - - switch (tr->op) { - - case CON: - C_loc(tr->value); - return; - - case STRING: - C_lae_dlb(tr->value, 0); - fromnativeaddr(); - return; - - case NAME: /* only rvalue */ - bs = (struct hshtab *) tr->tr1; - if (bs->class == EXTERN) - C_loe_dnam(manglename(bs->name, 'b'), 0); - else if (bs->class == AUTO) - C_lol(bs->offset); - else - goto classerror; - return; - - case CALL: - stk = pushargs(tr->tr2); - rcexpr(tr->tr1); - tonativeaddr(); - C_cai(); - if (stk) - C_asp(stk); - C_lfr(wordsize); - return; - - case AMPER: - bs = (struct hshtab *) tr->tr1->tr1; - if (bs->class == EXTERN) { - C_lae_dnam(manglename(bs->name, 'b'), 0); - } else if (bs->class == AUTO) { - C_lal(bs->offset); - } else - goto classerror; - fromnativeaddr(); - return; - - case STAR: /* only rvalue */ - rcexpr(tr->tr1); - tonativeaddr(); - C_loi(wordsize); - return; - - case PLUS: - binary(tr); - C_adi(wordsize); - return; - - case MINUS: - binary(tr); - C_sbi(wordsize); - return; - - case TIMES: - binary(tr); - C_mli(wordsize); - return; - - case DIVIDE: - binary(tr); - C_dvi(wordsize); - return; - - case MOD: - binary(tr); - C_rmi(wordsize); - return; - - case AND: - binary(tr); - C_and(wordsize); - return; - - case OR: - binary(tr); - C_ior(wordsize); - return; - - case EOR: - binary(tr); - C_xor(wordsize); - return; - - case LSHIFT: - binary(tr); - C_sli(wordsize); - return; - - case RSHIFT: - binary(tr); - C_sri(wordsize); - return; - - case EQUAL: - case NEQUAL: - case LESS: - case LESSEQ: - case GREAT: - case GREATEQ: - binary(tr); - C_cmi(wordsize); - switch (tr->op) { - case EQUAL: - C_teq(); - break; - case NEQUAL: - C_tne(); - break; - case LESS: - C_tlt(); - break; - case LESSEQ: - C_tle(); - break; - case GREAT: - C_tgt(); - break; - case GREATEQ: - C_tge(); - break; - } - return; - - case EXCLA: - rcexpr(tr->tr1); - C_teq(); - return; - - case NEG: - rcexpr(tr->tr1); - C_ngi(wordsize); - return; - - case NOT: - rcexpr(tr->tr1); - C_com(wordsize); - return; - - case QUEST: - cbranch(tr->tr1, o1=isn++); - rcexpr(tr->tr2->tr1); - jump(o2 = isn++); - fnlabel(o1); - rcexpr(tr->tr2->tr2); - fnlabel(o2); - return; - - default: - error("Can't print tree (op: %d)", tr->op); - } - -classerror: - error("Storage class"); -} - -/* Prints the tree in RPN, for debugging */ -/* -void -rcexpr(struct tnode *tr) -{ - struct hshtab *bs; - - if (tr == NULL) - printf("(NULL) "); - else if (tr->op == CON) - printf("%d ", tr->value); - else if (tr->op == STRING) - printf("s(L%d) ", tr->value); - else if (tr->op == NAME) { - bs = (struct hshtab *)tr->tr1; - if (bs->class == AUTO) - printf("%s(%d) ", bs->name, bs->offset); - else - printf("%s ", bs->name); - } else { - rcexpr(tr->tr1); - if (opdope[tr->op]&01) - rcexpr(tr->tr2); - printtoken(tr->op, stdout); - } -} -*/ diff --git a/lang/b/compiler/build.lua b/lang/b/compiler/build.lua deleted file mode 100644 index a195b7fdd9..0000000000 --- a/lang/b/compiler/build.lua +++ /dev/null @@ -1,29 +0,0 @@ - -cprogram { - name = "em_b", - srcs = { - "./b0.c", - "./b1.c", - }, - deps = { - "./b.h", - "modules+headers", - "modules/src/alloc+lib", - "modules/src/data+lib", - "modules/src/em_code+lib_k", - "modules/src/em_data+lib", - "modules/src/em_mes+lib", - "modules/src/print+lib", - "modules/src/string+lib", - "modules/src/system+lib", - } -} - -installable { - name = "pkg", - map = { - ["$(PLATDEP)/em_b"] = "+em_b", - ["$(INSDIR)/share/man/man6/em_b.6"] = "./em_b.6" - } -} - diff --git a/lang/b/compiler/em_b.6 b/lang/b/compiler/em_b.6 deleted file mode 100644 index f7030f214c..0000000000 --- a/lang/b/compiler/em_b.6 +++ /dev/null @@ -1,53 +0,0 @@ -.TH EM_B 6 2017-01-18 -.ad -.SH NAME -em_b \- ACK B compiler -.SH SYNOPSIS -.B ~em/lib/ack/em_b -.RI [ options ] -.SH DESCRIPTION -.I em_b -is a port of the ABC B compiler to the ACK. -Interested parties will be -interested in the upstream distribution here: -.nf -.sp -https://github.com/aap/abc -.fi -.PP -However, the version here has been heavily modified \(em bug reports should be -filed with the ACK, not with the upstream compiler. -.PP -Since B was designed for machines with word addressing, some hacking is -required to make it work on modern, byte addressed machines. -The generated -code expects B variables to contain word addresses, and then generates -code to transform these into native addresses before use (which, -unfortunately, impacts performance). -However, the ACK's linker doesn't know -how to emit word addresses into the program's data sections, and so a -separate fixup stage has to happen at runtime, just before \fBmain()\fP, -to convert the byte addresses into word addresses. -.PP -The end result is that using multiple source files with B is somewhat -unwieldy, requiring each module to be explicitly named and then an extra -stage to generate the fixup code. -See the \fBack\fP(1) and \fBabmodules\fP(1) for details. -.SH OPTIONS -.I em_b -accepts the following flags: -.IP \-w\ \fIsize\fP -Sets the word size, used for scaling addresses. -Usually either 2 or 4. -.IP \-B\ \fIname\fP -Sets the name of the module currently being compiled (used to generate the -fixup table symbol name). -Defaults to \fImain\fP if not specified. -.IP \-i\ \fIfilename\fP -The source B file. -.IP \-o\ \fIfilename\fP -The output compact EM bytecode file. -.SH SEE ALSO -\fIack\fR(1), \fIabmodules\fR(1) -.SH REMARKS -It is very unlikely the \fIem_b\fP will ever be useful for anything. diff --git a/lang/b/distr/Makefile b/lang/b/distr/Makefile deleted file mode 100644 index 2838486472..0000000000 --- a/lang/b/distr/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -CFLAGS=-Wall -Wextra -b: b0.o b1.o - cc b0.o b1.o -o b -b0.o: b0.c b.h -b1.o: b1.c b.h - -libs: - ./abc -c brt.s lib.b - -install: b abc - cp abc $(HOME)/bin - -%.o: %.s - as --32 $^ -o $@ - diff --git a/lang/b/distr/abc b/lang/b/distr/abc deleted file mode 100755 index 21cdda4854..0000000000 --- a/lang/b/distr/abc +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/sh -BDIR="$HOME/abc" -objs="$BDIR/brt.o $BDIR/lib.o" -BC="$BDIR/b" - -# compile in.b [out.s] -compile() { - if [ "${1##*.}" != "b" ]; then - echo "Error: can only compile b files" >&2 - exit 1 - fi - cout=$2 - [ "$cout" != "" ] || cout=${1%b}s - tmp1=`mktemp`; tmp2=`mktemp` - $BC $1 $tmp2 $tmp1 - retval=$? - cat $tmp1 $tmp2 > $cout - rm $tmp1 $tmp2 - [ $retval -eq 0 ] || rm $cout && return $retval - echo $cout - return $retval -} - -# assemble in.{sb} [out.o] -assemble() { - atmp="" - ain=$1 - aout=$2; - if [ "${1##*.}" = "b" ]; then - [ "$aout" != "" ] || aout=${ain%b}o - ain=`mktemp --suffix=.s` - compile $1 $ain >/dev/null || return 1 - atmp="foo" - elif [ "${1##*.}" = "s" ]; then - [ "$aout" != "" ] || aout=${ain%s}o - else - echo "Error: can only compile b and s files" >&2 - exit 1 - fi - as --32 -g $ain -o $aout - [ "$atmp" != "" ] && rm $ain - echo $aout -} - -out="" -action="link" -while getopts "o:Sc" o -do case "$o" in - o) out="$OPTARG";; - S) action=compile;; - c) action=assemble;; - esac -done -shift $(($OPTIND - 1)) - -# ignore -o option if more than one file given and not linking objs -if [ $# -gt 1 ]; then - if [ "$action" != "link" ]; then - out="" - fi -fi - -[ $# -ne 1 ] && havelist=yes -tmpobjs="" -for i in $@; do - if [ "$action" != "link" ]; then - [ "$havelist" = "yes" ] && echo $i: - $action $i $out >/dev/null - [ $? -eq 0 ] || break=1 - else - if [ "${i##*.}" = "o" ]; then - objs="$objs $i" - else - [ "$havelist" = "yes" ] && echo $i: - ltmp=`mktemp --suffix=.o` - tmpobjs="$tmpobjs $ltmp" - assemble $i $ltmp >/dev/null - [ $? -eq 0 ] || break=1 - fi - fi -done -if [ $break ]; then - [ "$tmpobjs" = "" ] || rm $tmpobjs - echo "Error" >&2 - exit 1 -fi -if [ "$action" = "link" ]; then - if [ "$out" = "" ]; then - out="-o a.out" - else - out="-o $out" - fi - ld -m elf_i386 -T $BDIR/link.ld $out $objs $tmpobjs - rm $tmpobjs -fi diff --git a/lang/b/distr/brt.s b/lang/b/distr/brt.s deleted file mode 100644 index 18f4fb351c..0000000000 --- a/lang/b/distr/brt.s +++ /dev/null @@ -1,151 +0,0 @@ - .globl _argv - .data - .align 4 - .comm argstr,256,4 -_argv: .long 0 - - .text - .globl start -start: - # clear bss (could be done better) - # is it actually necessary? - mov $__bss,%eax -1: - movb $0,(%eax) - inc %eax - cmp $__ebss,%eax - jbe 1b - - # copy command line args (can't use them directly, not aligned) - mov %esp,%eax - shr $2,%eax - mov %eax,_argv - mov (%esp),%ecx # number of arguments - mov $argstr,%edi -1: - mov (%esp,%ecx,4),%esi - mov %edi,%eax - shr $2,%eax - mov %eax,(%esp,%ecx,4) - call cpystr - loop 1b - - call bsymbs - mov _main,%eax - shl $2,%eax - call *%eax - mov %eax,%ebx - mov $1,%eax - int $0x80 - -# copy string from esi to edi and convert '\0' to B's '*e', align edi -cpystr: - mov (%esi),%al - test %al,%al - jz 1f - mov %al,(%edi) - inc %edi - inc %esi - jmp cpystr -1: - movb $04,(%edi) - inc %edi - add $3,%edi - and $~3,%edi - ret - -# shift addresses filled in by the linker 2 bits to the right -# so B only ever sees word addresses -bsymbs: - mov $__bsymb,%eax -1: - cmp $__ebsymb,%eax - jge 1f - mov (%eax),%ebx - mov (%ebx),%ecx - shr $2,%ecx - mov %ecx,(%ebx) - add $4,%eax - jmp 1b -1: - ret - - .globl retrn -retrn: - mov %ebp,%esp - pop %ebp - ret - -# handle switch table: -# eax has the value, ebx the address of the switch table - .globl bswitch -bswitch: - xor %ecx,%ecx -1: - mov (%ebx,%ecx,8),%edx - mov 4(%ebx,%ecx,8),%edi - test %edi,%edi - jz 1f # default (last in table) - cmp %eax,%edx - je 2f - inc %ecx - jmp 1b -1: - jmp *%edx -2: - jmp *%edi - -# -# Library functions in assembly -# - .globl _exit - .data - .align 4 - .section .bsymb; .long _exit; .data -_exit: .long 1f - .text - .align 4 -1: mov $1,%eax - mov $0,%ebx - int $0x80 - - .globl _write - .data - .align 4 - .section .bsymb; .long _write; .data -_write: .long 1f - .text - .align 4 -1: mov 4(%esp),%ebx - mov 8(%esp),%ecx - shl $2,%ecx - mov 12(%esp),%edx - mov $4,%eax - int $0x80 - ret - - .globl _read - .data - .align 4 - .section .bsymb; .long _read; .data -_read: .long 1f - .text - .align 4 -1: mov 4(%esp),%ebx - mov 8(%esp),%ecx - shl $2,%ecx - mov 12(%esp),%edx - mov $3,%eax - int $0x80 - ret - - .globl _inv - .data - .align 4 - .section .bsymb; .long _inv; .data -_inv: .long 1f - .text - .align 4 -1: mov 4(%esp),%eax - not %eax - ret diff --git a/lang/b/distr/examples/1_var.b b/lang/b/distr/examples/1_var.b deleted file mode 100644 index aa315442f1..0000000000 --- a/lang/b/distr/examples/1_var.b +++ /dev/null @@ -1,7 +0,0 @@ -main() { - auto a, b, c, sum; - - a = 1; b = 2; c = 3; - sum = a+b+c; - putnumb(sum); -} diff --git a/lang/b/distr/examples/2_ext.b b/lang/b/distr/examples/2_ext.b deleted file mode 100644 index a8deac665a..0000000000 --- a/lang/b/distr/examples/2_ext.b +++ /dev/null @@ -1,9 +0,0 @@ -main() { - extrn a, b, c; - putchar(a); putchar(b); putchar(c); putchar('!*n'); -} - -a 'hell'; -b 'o, w'; -c 'orld'; - diff --git a/lang/b/distr/examples/3_fun.b b/lang/b/distr/examples/3_fun.b deleted file mode 100644 index 16d7409643..0000000000 --- a/lang/b/distr/examples/3_fun.b +++ /dev/null @@ -1,13 +0,0 @@ -main() { - extrn a, b, c, d; - put2char(a,b); - put2char(c,d); -} - -put2char(x,y) { -putchar(x); -putchar(y); -} - -a 'hell'; b 'o, w'; c 'orld'; d '!*n'; - diff --git a/lang/b/distr/examples/4_goto.b b/lang/b/distr/examples/4_goto.b deleted file mode 100644 index 2d5256afce..0000000000 --- a/lang/b/distr/examples/4_goto.b +++ /dev/null @@ -1,7 +0,0 @@ -main() { - auto c; -read: - c= getchar(); - putchar(c); - if(c != '*n') goto read; -} diff --git a/lang/b/distr/examples/5_while.b b/lang/b/distr/examples/5_while.b deleted file mode 100644 index 13baa0cace..0000000000 --- a/lang/b/distr/examples/5_while.b +++ /dev/null @@ -1,10 +0,0 @@ -main() { - auto c; - while (1) { - while ( (c=getchar()) != ' ') - if (putchar(c) == '*n') exit(); - putchar( '*n' ); - while ( (c=getchar()) == ' '); /* skip blanks */ - if (putchar(c)=='*n') exit(); - } -} diff --git a/lang/b/distr/examples/printargs.b b/lang/b/distr/examples/printargs.b deleted file mode 100644 index 444932054c..0000000000 --- a/lang/b/distr/examples/printargs.b +++ /dev/null @@ -1,10 +0,0 @@ -main() { - extrn argv; - auto i; - - i = 1; - printf("%d args:*n", argv[0]); - while (i <= argv[0]) - printf("%s*n", argv[i++]); - return(0); -} diff --git a/lang/b/distr/lib.b b/lang/b/distr/lib.b deleted file mode 100644 index 9e274eb928..0000000000 --- a/lang/b/distr/lib.b +++ /dev/null @@ -1,111 +0,0 @@ -char(s, n) - return((s[n/4]>>8*(n%4))&0377); /* s[n/4] */ - -lchar(s, n, char) { - auto i; - i = 8*(n%4); - char = (char&0377)<> 8; - } - write(1, &char, 4-i); - return(char); -} - -getchar() { - auto char; - - char = 0; - read(1, &char, 1); - return(char); -} - -printn(n,b) { - extrn putchar; - auto a; - - if (a = n/b) - printn(a, b); - putchar(char("0123456789ABCDEF", n%b)); -} - -putnumb(n) { - printn(n,10); - putchar('*n'); -} - -putstr(s) { - auto c, i; - - i = 0; - while ((c = char(s,i++)) != '*e') - putchar(c); -} - -getstr(s) { - auto c, i; - - while ((c = getchar()) != '*n') - lchar(s,i++,c); - lchar(s,i,'*e'); - return(s); -} - -printf(fmt, x1,x2,x3,x4,x5,x6,x7,x8,x9) { - extrn printn, char, putchar; - auto adx, x, c, i, j; - - i = 0; - adx = &x1; -loop: - while((c=char(fmt,i++)) != '%') { - if(c == '*e') - return; - putchar(c); - } - x = *adx++; - switch (c = char(fmt,i++)) { - - case 'd': - case 'o': - if(x < 0) { - x = -x; - putchar('-'); - } - printn(x, c=='o'?8:10); - goto loop; - - case 'x': - if(x < 0) { - x = -x; - putchar('-'); - } - printn(x, 16); - goto loop; - - case 'c': - putchar(x); - goto loop; - - case 's': - j = 0; - while((c=char(x,j++)) != '*e') - putchar(c); - goto loop; - } - putchar('%'); - i--; - adx--; - goto loop; -} - diff --git a/lang/b/distr/link.ld b/lang/b/distr/link.ld deleted file mode 100644 index fd0fb71ce4..0000000000 --- a/lang/b/distr/link.ld +++ /dev/null @@ -1,21 +0,0 @@ -OUTPUT_FORMAT("elf32-i386") -OUTPUT_ARCH(i386) - -ENTRY(start) - -SECTIONS -{ - . = 0x400000; - .text : { *(.text) } - . = 0x8000000; - .data : { - *(.data) - __bsymb = .; - *(.bsymb) - __ebsymb = .; - } - . = ALIGN(16); - __bss = .; - .bss : { *(.bss) } - __ebss = .; -} diff --git a/lang/b/lib/b.h b/lang/b/lib/b.h deleted file mode 100644 index 36d9f38fd2..0000000000 --- a/lang/b/lib/b.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef B_H -#define B_H - -#include -#include - -#if EM_PSIZE == 2 -#define SHIFT 1 -#elif EM_PSIZE == 4 -#define SHIFT 2 -#elif EM_PSIZE == 8 -#define SHIFT 3 -#else -#error Unsupported EM_PSIZE -#endif - -#define MASK ((1< -#include -#include - -void binit(void) -{ - patch_addresses(bmodule_main); -} - diff --git a/lang/b/lib/main.c b/lang/b/lib/main.c deleted file mode 100644 index 1c3ce67a28..0000000000 --- a/lang/b/lib/main.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "b.h" -#include -#include -#include - -extern intptr_t i_main(intptr_t argc, const char* argv[]); - -FILE* input_unit; -FILE* output_unit; - -static intptr_t i_char(intptr_t s, intptr_t n) -{ - const char* p = (const char*)(s< 0); - - do - fputc(s[--i], output_unit); - while (i > 0); -} - -static void i_printf(intptr_t s, ...) -{ - char* p = (char*)(s<>= SHIFT; - } -} - -int main(int argc, const char* argv[]) -{ - patch_addresses(bmodule_stdlib); - binit(); - input_unit = stdin; - output_unit = stdout; - return i_main(argc, NULL); -} diff --git a/lib/descr/fe b/lib/descr/fe index 673270c2da..f387adf170 100644 --- a/lib/descr/fe +++ b/lib/descr/fe @@ -170,17 +170,6 @@ name a68s need .8 callname a68s end -name b - from .b - to .k - program {EM}/lib/ack/em_b - mapflag -B* ABC_F={ABC_F?} -B* - args -i < -o > -w {p} {ABC_F?} - prep cond - rts .b - need .b - callname abc -end name encode from .e to .k diff --git a/plat/build.lua b/plat/build.lua index e0519dc1ab..de2fada163 100644 --- a/plat/build.lua +++ b/plat/build.lua @@ -20,7 +20,6 @@ definerule("ackfile", name = e.name, srcs = e.srcs, deps = { - "lang/b/compiler+pkg", "lang/basic/src+pkg", "lang/cem/cemcom.ansi+pkg", "lang/cem/cpp.ansi+pkg", @@ -133,12 +132,10 @@ definerule("build_plat_libs", }, function(e) local installmap = { - "lang/b/lib+pkg_"..e.plat, "lang/basic/lib+pkg_"..e.plat, "lang/cem/libcc.ansi+pkg_"..e.plat, "lang/m2/libm2+pkg_"..e.plat, "lang/pc/libpc+pkg_"..e.plat, - "lang/b/lib+pkg_"..e.plat, ["$(PLATIND)/"..e.plat.."/libem.a"] = "mach/"..e.arch.."/libem+lib_"..e.plat, ["$(PLATIND)/"..e.plat.."/libend.a"] = "mach/"..e.arch.."/libend+lib_"..e.plat, } diff --git a/tests/plat/b/build.lua b/tests/plat/b/build.lua deleted file mode 100644 index 841c496126..0000000000 --- a/tests/plat/b/build.lua +++ /dev/null @@ -1,9 +0,0 @@ -bundle { - name = "srcs", - srcs = { - "./control_b.b", - "./incdec_b.b", - "./operators_b.b", - } -} - diff --git a/tests/plat/b/control_b.b b/tests/plat/b/control_b.b deleted file mode 100644 index a31b9d380f..0000000000 --- a/tests/plat/b/control_b.b +++ /dev/null @@ -1,107 +0,0 @@ -# -zero 0; -one 1; - -if_t() -{ - extrn zero, one; - auto fails, successes; - - successes = 0; - - if (zero) - fail(__LINE__); - - if (zero) - fail(__LINE__); - else - successes++; - - if (one) - successes++; - - if (one) - successes++; - else - fail(__LINE__); - - if (successes != 3) - fail(__LINE__); -} - -while_t() -{ - extrn zero, one; - auto successes, count; - - successes = 3; - count = 0; - while (count) - { - successes++; - count--; - } - if (successes != 3) - fail(__LINE__); - - while (zero) - fail(__LINE__); - - while (one) - { - break; - fail(__LINE__); - } -} - -sdata(n) -{ - switch (n) - { - case 0: return(0); - case 1: return(1); - case 100: return(100); - default: return(-1); - } -} - -switch_t() -{ - extrn zero; - auto successes; - - if (!(sdata(-1) == -1)) fail(__LINE__); - if (!(sdata(0) == 0)) fail(__LINE__); - if (!(sdata(1) == 1)) fail(__LINE__); - if (!(sdata(2) == -1)) fail(__LINE__); - if (!(sdata(100) == 100)) fail(__LINE__); - if (!(sdata(200) == -1)) fail(__LINE__); - - successes = 0; - switch (zero) - { - case 0: /* fall through */ - case 1: successes++; break; - } - if (successes != 1) - fail(__LINE__); -} - -goto_t() -{ - goto n; - fail(__LINE__); - n:; -} - -main() -{ - if_t(); - switch_t(); - goto_t(); - while_t(); - - finished(); - return(0); -} - diff --git a/tests/plat/b/incdec_b.b b/tests/plat/b/incdec_b.b deleted file mode 100644 index 4edf5f6bf6..0000000000 --- a/tests/plat/b/incdec_b.b +++ /dev/null @@ -1,82 +0,0 @@ -# -/* External variables to defeat constant folding. */ -zero 0; -one 1; - -i 0; - -ext_t() -{ - extrn zero, one, i; - - i = zero; - if (!(i++ == 0)) fail(__LINE__); - - i = one; - if (!(i-- == 1)) fail(__LINE__); - if (!(i == 0)) fail(__LINE__); - - i = zero; - if (!(++i == 1)) fail(__LINE__); - if (!(i == 1)) fail(__LINE__); - - i = one; - if (!(--i == 0)) fail(__LINE__); - if (!(i == 0)) fail(__LINE__); -} - -int_t() -{ - extrn zero, one; - auto i; - - i = zero; - if (!(i++ == 0)) fail(__LINE__); - - i = one; - if (!(i-- == 1)) fail(__LINE__); - if (!(i == 0)) fail(__LINE__); - - i = zero; - if (!(++i == 1)) fail(__LINE__); - if (!(i == 1)) fail(__LINE__); - - i = one; - if (!(--i == 0)) fail(__LINE__); - if (!(i == 0)) fail(__LINE__); -} - -star_t() -{ - extrn zero, one, i; - auto p; - - p = &i; - - i = zero; - if (!((*p)++ == 0)) fail(__LINE__); - - i = one; - if (!((*p)-- == 1)) fail(__LINE__); - if (!(i == 0)) fail(__LINE__); - - i = zero; - if (!(++(*p) == 1)) fail(__LINE__); - if (!(i == 1)) fail(__LINE__); - - i = one; - if (!(--(*p) == 0)) fail(__LINE__); - if (!(i == 0)) fail(__LINE__); -} - -main() -{ - ext_t(); - int_t(); - star_t(); - - finished(); - return(0); -} - - diff --git a/tests/plat/b/operators_b.b b/tests/plat/b/operators_b.b deleted file mode 100644 index 5baa674b10..0000000000 --- a/tests/plat/b/operators_b.b +++ /dev/null @@ -1,69 +0,0 @@ -# -minusone -1; -zero 0; -one 1; -two 2; - -main() -{ - extrn minusone, zero, one, two; - auto i, j; - - if (!(zero == 0)) fail(__LINE__); - if (!(one == 1)) fail(__LINE__); - if (!(-one == -1)) fail(__LINE__); - if (!(!one == 0)) fail(__LINE__); - if (!(!zero == 1)) fail(__LINE__); - if (!(~zero == -1)) fail(__LINE__); - if (!(~minusone == 0)) fail(__LINE__); - - if (!(zero == zero)) fail(__LINE__); - if (!(zero != one)) fail(__LINE__); - if (!(zero < one)) fail(__LINE__); - if (!(zero <= one)) fail(__LINE__); - if (!(zero <= zero)) fail(__LINE__); - if (!(one > zero)) fail(__LINE__); - if (!(one >= zero)) fail(__LINE__); - if (!(one >= one)) fail(__LINE__); - - if (!((two + two) == 4)) fail(__LINE__); - if (!((two - two) == 0)) fail(__LINE__); - if (!((two * two) == 4)) fail(__LINE__); - if (!((two / two) == 1)) fail(__LINE__); - if (!((two % two) == 0)) fail(__LINE__); - - if (!((one << 1) == 2)) fail(__LINE__); - if (!((two >> 1) == 1)) fail(__LINE__); - - if (!((two & 1) == 0)) fail(__LINE__); - if (!((two | 1) == 3)) fail(__LINE__); - if (!((two ^ 2) == 0)) fail(__LINE__); - - i = 2; i =+ two; if (!(i == 4)) fail(__LINE__); - i = 2; i =- two; if (!(i == 0)) fail(__LINE__); - i = 2; i =* two; if (!(i == 4)) fail(__LINE__); - i = 2; i =/ two; if (!(i == 1)) fail(__LINE__); - i = 2; i =% two; if (!(i == 0)) fail(__LINE__); - - i = zero; i === zero; if (!i) fail(__LINE__); - i = zero; i =!= one; if (!i) fail(__LINE__); - i = zero; i =< one; if (!i) fail(__LINE__); - i = zero; i =<= one; if (!i) fail(__LINE__); - i = zero; i =<= zero; if (!i) fail(__LINE__); - i = one; i => zero; if (!i) fail(__LINE__); - i = one; i =>= zero; if (!i) fail(__LINE__); - i = one; i =>= one; if (!i) fail(__LINE__); - - i = one; i =<< one; if (!(i == 2)) fail(__LINE__); - i = two; i =>> one; if (!(i == 1)) fail(__LINE__); - - i = two; i =& 1; if (!(i == 0)) fail(__LINE__); - i = two; i =| 1; if (!(i == 3)) fail(__LINE__); - i = two; i =^ 2; if (!(i == 0)) fail(__LINE__); - - if (!(one ? 1 : 0)) fail(__LINE__); - if (!(zero ? 0 : 1)) fail(__LINE__); - - finished(); - return(0); -} diff --git a/tests/plat/build.lua b/tests/plat/build.lua index cbc5632d19..d95e554a6b 100644 --- a/tests/plat/build.lua +++ b/tests/plat/build.lua @@ -6,7 +6,7 @@ definerule("plat_testsuite", plat = { type="string" }, method = { type="string" }, -- added bugs/bug-203-ego-sr_c-O3.c - sets = { type="table", default={"core", "b", "bugs", "m2", "floats", "long-long"}}, + sets = { type="table", default={"core", "bugs", "m2", "floats", "long-long"}}, skipsets = { type="table", default={}}, tests = { type="targets", default={} }, }, @@ -31,7 +31,6 @@ definerule("plat_testsuite", name = "lib", srcs = { "tests/plat/lib/test.c", - "tests/plat/lib/test_b.c", }, hdrs = { "tests/plat/lib/test.h", diff --git a/tests/plat/lib/test_b.c b/tests/plat/lib/test_b.c deleted file mode 100644 index 85ce1a159b..0000000000 --- a/tests/plat/lib/test_b.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "test.h" - -extern void patch_addresses(uintptr_t** module); -extern uintptr_t* bmodule_main[]; - -static void i_writehex(intptr_t code) -{ - writehex(code); -} - -static void i_fail(intptr_t code) -{ - fail(code); -} - -uintptr_t b_finished = (uintptr_t)&finished; -uintptr_t b_writehex = (uintptr_t)&i_writehex; -uintptr_t b_fail = (uintptr_t)&i_fail; - -static uintptr_t* bmodule_test[] = -{ - &b_finished, - &b_writehex, - &b_fail, - 0 -}; - -void binit(void) -{ - patch_addresses(bmodule_test); - patch_addresses(bmodule_main); -} - diff --git a/util/ack/ack.1.X b/util/ack/ack.1.X index 4d1e0d6af6..3058989a27 100644 --- a/util/ack/ack.1.X +++ b/util/ack/ack.1.X @@ -42,8 +42,6 @@ but the following are recognized by most machines: Pascal program. .IP .c C module. -.IP .b -B module. .IP .bas Basic program. .IP .ocm @@ -136,14 +134,6 @@ These routines are supplied with one parameter, a pointer to a string containing the name of the routine. . .sp 1 -.IP \-B\fIname\fP -Tells the B front end what the name of the module being compiled is, for use -with separate compilation. -Defaults to -.I main -if not specified. See the section below on compiling B. -. -.sp 1 .IP \-O .IP \-O\fInum\fP .IP \-O\fIopt1,opt2,...\fP @@ -345,39 +335,6 @@ these names. .PP The default directories searched for include files differ for each machine. . -.SH COMPILING B -B programs have special needs when compiled with the ACK. -B modules have to be -initialised before use, to convert pointer addresses to word addresses; this is -done automatically when compiling a single B source file to an executable, but -must be done manually when using separate compilation. -.PP -To do this, compile your B modules with the \fI-B\fP option as usual, and then -use the -.B abmodules -program to scan the object files and emit a C file which performs the -initialisation. -Then compile this as well into an object file, and link the -whole lot together. -The result will be a runnable executable. -.PP -Beware \(em referring to an uninitialised module will cause your program to -crash! -.PP -The default initialiser in the B standard library looks for a module called -\fBmain\fP. -.PP -For example: -.nf -.sp -ack -c -mpc86 thismodule.b -Bthismodule -ack -c -mpc86 thatmodule.b -Bthatmodule -ack -c -mpc86 theothermodule.b -Btheothermodule -abmodules -o binit.c thismodule.o thatmodule.o theothermodule.o -ack -c -mpc86 binit.c -ack -mpc86 -o pc86.exe thismodule.o thatmodule.o theothermodule.o binit.o -.fi -. .SH PROGRAMS \fIAck\fP uses one or more programs in each phase of the transformation. diff --git a/util/amisc/abmodules.1 b/util/amisc/abmodules.1 deleted file mode 100644 index 1eb67d843d..0000000000 --- a/util/amisc/abmodules.1 +++ /dev/null @@ -1,25 +0,0 @@ -.TH ABMODULES 1 2017-01-18 -.SH NAME -abmodules \- find B modules -.SH SYNOPSIS -abmodules [ \-o outputfile.c ] [ file ... ] -.SH DESCRIPTION -.I abmodules -finds B modules in a set of ack.out(5) format object files, and either lists -them or generates a C file which initialises the modules. -.PP -This tool is used for multiple compilation of B programs; B modules must be -initialised before use, and this tool generates the initialisation code for -programs containing an abitrary number of modules. -See em_b(6) for details. -.PP -Options are: -.TP -.B \-o filename -Write C source to -.I filename -containing a definition of a binit() function which will initalise all modules -found. -If not present, a simple list of module names is written to stdout instead. -.SH SEE ALSO -ack.out(5), em_b(6) diff --git a/util/amisc/abmodules.c b/util/amisc/abmodules.c deleted file mode 100644 index c3807484b4..0000000000 --- a/util/amisc/abmodules.c +++ /dev/null @@ -1,210 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "out.h" -#include "arch.h" -#include "ranlib.h" -#include "object.h" -#include "warnings.h" -#include "stringlist.h" - -int numsort_flg; -int sectsort_flg; -int undef_flg; -int revsort_flg = 1; -int globl_flg; -int nosort_flg; -int arch_flg; -int prep_flg; -int read_error; -struct outsect sbuf; -long off; -long s_base[S_MAX]; /* for specially encoded bases */ -char* filename; -int narg; - -static const char prefix[] = "_bmodule_"; - -static struct stringlist modules; - -static void do_file(FILE* fd) -{ - struct outhead hbuf; - char* cbufp; - long fi_to_co; - long n; - unsigned readcount; - - read_error = 0; - rd_fdopen(fd); - - rd_ohead(&hbuf); - if (BADMAGIC(hbuf)) - return; - - n = hbuf.oh_nname; - if (n == 0) - fatal("%s --- no name list", filename); - - if (hbuf.oh_nchar == 0) - fatal("%s --- no names", filename); - - if ((readcount = hbuf.oh_nchar) != hbuf.oh_nchar) - fatal("%s --- string area too big", filename); - - cbufp = calloc(readcount, 1); - rd_string(cbufp, hbuf.oh_nchar); - if (read_error) - goto corrupt; - - fi_to_co = (long)(cbufp - OFF_CHAR(hbuf)); - while (--n >= 0) - { - struct outname nbuf; - - rd_name(&nbuf, 1); - if (read_error) - goto corrupt; - - if (!(nbuf.on_type & S_EXT)) - continue; - if ((nbuf.on_type & S_TYP) == S_UND) - continue; - - if (nbuf.on_foff == 0) - nbuf.on_mptr = 0; - else - nbuf.on_mptr = (char*)(nbuf.on_foff + fi_to_co); - - if (strlen(nbuf.on_mptr) <= sizeof(prefix)) - continue; - if (memcmp(nbuf.on_mptr, prefix, sizeof(prefix) - 1) != 0) - continue; - - stringlist_add(&modules, strdup(nbuf.on_mptr + sizeof(prefix) - 1)); - } - - if (cbufp) - free(cbufp); - - return; -corrupt: - fatal("%s --- corrupt", filename); -} - -static void process(FILE* fd) -{ - uint16_t magic = rd_unsigned2(fd); - switch (magic) - { - case O_MAGIC: - fseek(fd, 0L, SEEK_SET); - do_file(fd); - break; - - case ARMAG: - case AALMAG: - { - struct ar_hdr archive_header; - static char buf[sizeof(archive_header.ar_name) + 1]; - - while (rd_arhdr(fd, &archive_header)) - { - long nextpos = ftell(fd) + archive_header.ar_size; - if (nextpos & 1) - nextpos++; - - strncpy(buf, archive_header.ar_name, sizeof(archive_header.ar_name)); - filename = buf; - if (strcmp(filename, SYMDEF) != 0) - do_file(fd); - fseek(fd, nextpos, SEEK_SET); - } - break; - } - - default: - fatal("file %s is of unknown format", filename); - } -} - -int main(int argc, char* const argv[]) -{ - FILE* outputfp = NULL; - - program_name = argv[0]; - for (;;) - { - int opt = getopt(argc, argv, "o:"); - if (opt == -1) - break; - - switch (opt) - { - case 'o': - outputfp = fopen(optarg, "wb"); - if (!outputfp) - fatal("cannot open output file: %s", strerror(errno)); - break; - - default: - fatal("usage: abmodules [-o outputfile] [file...]"); - } - } - - for (;;) - { - FILE* fd; - - filename = argv[optind++]; - if (!filename) - break; - if ((fd = fopen(filename, "rb")) == NULL) - fatal("cannot open %s: %s", filename, strerror(errno)); - process(fd); - fclose(fd); - } - - if (outputfp) - { - struct stringfragment* f; - - fprintf(outputfp, "#include \n"); - fprintf(outputfp, "\n"); - - for (f = modules.first; f; f = f->next) - fprintf(outputfp, "extern uintptr_t bmodule_%s[];\n", f->data); - - fprintf(outputfp, "\n"); - fprintf(outputfp, "extern void patch_addresses(uintptr_t* module);\n"); - fprintf(outputfp, "\n"); - fprintf(outputfp, "void binit(void) {\n"); - for (f = modules.first; f; f = f->next) - fprintf(outputfp, "\tpatch_addresses(bmodule_%s);\n", f->data); - fprintf(outputfp, "}\n"); - fclose(outputfp); - } - else - { - struct stringfragment* f; - - for (f = modules.first; f; f = f->next) - printf("%s\n", f->data); - } - - exit(0); -} - -void rd_fatal(void) -{ - fatal("read error on %s", filename); -} diff --git a/util/amisc/build.lua b/util/amisc/build.lua index 22fa396cfb..e06bf83a16 100644 --- a/util/amisc/build.lua +++ b/util/amisc/build.lua @@ -20,7 +20,6 @@ local function simpleprogram(name) } end -simpleprogram("abmodules") simpleprogram("aelflod") simpleprogram("anm") simpleprogram("ashow") @@ -31,7 +30,6 @@ simpleprogram("astrip") installable { name = "pkg", map = { - "+abmodules-pkg", "+aelflod-pkg", "+anm-pkg", "+ashow-pkg",