diff --git a/lang/b/compiler/b.h b/lang/b/compiler/b.h index 61548b6e8..acfb4a966 100644 --- a/lang/b/compiler/b.h +++ b/lang/b/compiler/b.h @@ -4,6 +4,7 @@ #include #include #include +#include "astring.h" #define NCPS 8 /* chars per symbol */ #define HSHSIZ 400 /* hash table size */ @@ -40,6 +41,7 @@ struct swtab { }; extern int wordsize; +extern const char* modulename; int paramsize; struct hshtab hshtab[HSHSIZ]; int hshused; @@ -89,6 +91,7 @@ char* manglename(char* name, char prefix); #define RPARN 7 #define COLON 8 #define COMMA 9 +#define HASH 10 #define MCALL 15 #define CALL 16 diff --git a/lang/b/compiler/b0.c b/lang/b/compiler/b0.c index d0ea69826..3d87774a2 100644 --- a/lang/b/compiler/b0.c +++ b/lang/b/compiler/b0.c @@ -14,6 +14,7 @@ int contlab = -1; int brklab = -1; int wordsize = 4; +const char* modulename = "b_module_main"; int bsymb_part; int code_part; int string_part; @@ -38,7 +39,7 @@ main(int argc, char *argv[]) { for (;;) { - int opt = getopt(argc, argv, "-w:i:o:"); + int opt = getopt(argc, argv, "-w:B:i:o:"); if (opt == -1) break; @@ -47,6 +48,10 @@ main(int argc, char *argv[]) wordsize = atoi(optarg); break; + case 'B': + modulename = aprintf("b_module_%s", optarg); + break; + case 'i': if (freopen(optarg, "r", stdin) == NULL) { error("Can't find %s", optarg); @@ -62,7 +67,7 @@ main(int argc, char *argv[]) break; derfault: - error("Usage: em_b [-w wordsize] [-i inputfile] [-o outputfile]"); + error("Usage: em_b [-w wordsize] [-B modulename] [-i inputfile] [-o outputfile]"); exit(1); } } @@ -97,8 +102,8 @@ main(int argc, char *argv[]) if (string_part) C_insertpart(string_part); - C_exa_dnam("bsymb_patch_table"); - C_df_dnam("bsymb_patch_table"); + C_exa_dnam((char*) modulename); + C_df_dnam((char*) modulename); if (bsymb_part) C_insertpart(bsymb_part); C_rom_cst(0); @@ -340,11 +345,30 @@ loop: 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); @@ -1242,7 +1266,7 @@ char ctab[128] = { 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, UNKN, UNKN, MOD, AND, SQUOTE, + 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, diff --git a/lang/b/compiler/build.lua b/lang/b/compiler/build.lua index 82095a683..27564280d 100644 --- a/lang/b/compiler/build.lua +++ b/lang/b/compiler/build.lua @@ -8,6 +8,7 @@ cprogram { "./*.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", diff --git a/lang/b/lib/b.h b/lang/b/lib/b.h index 123eabc58..571c1794b 100644 --- a/lang/b/lib/b.h +++ b/lang/b/lib/b.h @@ -14,6 +14,9 @@ #error Unsupported EM_PSIZE #endif +extern FILE* input_unit; extern FILE* output_unit; +#define END 4 + #endif diff --git a/lang/b/lib/main.c b/lang/b/lib/main.c index 9b868bada..404e1fd9d 100644 --- a/lang/b/lib/main.c +++ b/lang/b/lib/main.c @@ -1,8 +1,12 @@ #include "b.h" +#include +#include +#include -extern uintptr_t* bsymb_patch_table[]; +extern uintptr_t* b_module_main[]; 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) @@ -19,7 +23,7 @@ static void i_lchar(intptr_t s, intptr_t n, intptr_t c) static intptr_t i_getchar(void) { - return fgetc(output_unit); + return fgetc(input_unit); } static intptr_t i_putchar(intptr_t c) @@ -28,17 +32,139 @@ static intptr_t i_putchar(intptr_t c) return c; } +static intptr_t i_putstr(intptr_t s) +{ + char* p = (char*)(s< 0); + + do + fputc(s[--i], output_unit); + while (i > 0); +} + +static void i_printf(intptr_t s, ...) +{ + char* p = (char*)(s<