First draft of the B module code; a module name can now be specified as a
compiler flag, which is used to set the name of the patch table. The compiler now understands C preprocessor line directives. Extend the standard library somewhat.
This commit is contained in:
parent
e3f8fb84dc
commit
ebd424e7f1
|
@ -4,6 +4,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <em.h>
|
#include <em.h>
|
||||||
|
#include "astring.h"
|
||||||
|
|
||||||
#define NCPS 8 /* chars per symbol */
|
#define NCPS 8 /* chars per symbol */
|
||||||
#define HSHSIZ 400 /* hash table size */
|
#define HSHSIZ 400 /* hash table size */
|
||||||
|
@ -40,6 +41,7 @@ struct swtab {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int wordsize;
|
extern int wordsize;
|
||||||
|
extern const char* modulename;
|
||||||
int paramsize;
|
int paramsize;
|
||||||
struct hshtab hshtab[HSHSIZ];
|
struct hshtab hshtab[HSHSIZ];
|
||||||
int hshused;
|
int hshused;
|
||||||
|
@ -89,6 +91,7 @@ char* manglename(char* name, char prefix);
|
||||||
#define RPARN 7
|
#define RPARN 7
|
||||||
#define COLON 8
|
#define COLON 8
|
||||||
#define COMMA 9
|
#define COMMA 9
|
||||||
|
#define HASH 10
|
||||||
|
|
||||||
#define MCALL 15
|
#define MCALL 15
|
||||||
#define CALL 16
|
#define CALL 16
|
||||||
|
|
|
@ -14,6 +14,7 @@ int contlab = -1;
|
||||||
int brklab = -1;
|
int brklab = -1;
|
||||||
|
|
||||||
int wordsize = 4;
|
int wordsize = 4;
|
||||||
|
const char* modulename = "b_module_main";
|
||||||
int bsymb_part;
|
int bsymb_part;
|
||||||
int code_part;
|
int code_part;
|
||||||
int string_part;
|
int string_part;
|
||||||
|
@ -38,7 +39,7 @@ main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int opt = getopt(argc, argv, "-w:i:o:");
|
int opt = getopt(argc, argv, "-w:B:i:o:");
|
||||||
if (opt == -1)
|
if (opt == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -47,6 +48,10 @@ main(int argc, char *argv[])
|
||||||
wordsize = atoi(optarg);
|
wordsize = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'B':
|
||||||
|
modulename = aprintf("b_module_%s", optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
if (freopen(optarg, "r", stdin) == NULL) {
|
if (freopen(optarg, "r", stdin) == NULL) {
|
||||||
error("Can't find %s", optarg);
|
error("Can't find %s", optarg);
|
||||||
|
@ -62,7 +67,7 @@ main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
derfault:
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,8 +102,8 @@ main(int argc, char *argv[])
|
||||||
if (string_part)
|
if (string_part)
|
||||||
C_insertpart(string_part);
|
C_insertpart(string_part);
|
||||||
|
|
||||||
C_exa_dnam("bsymb_patch_table");
|
C_exa_dnam((char*) modulename);
|
||||||
C_df_dnam("bsymb_patch_table");
|
C_df_dnam((char*) modulename);
|
||||||
if (bsymb_part)
|
if (bsymb_part)
|
||||||
C_insertpart(bsymb_part);
|
C_insertpart(bsymb_part);
|
||||||
C_rom_cst(0);
|
C_rom_cst(0);
|
||||||
|
@ -340,11 +345,30 @@ loop:
|
||||||
|
|
||||||
case NEWLN:
|
case NEWLN:
|
||||||
line++;
|
line++;
|
||||||
|
/* fall through */
|
||||||
case SPACE:
|
case SPACE:
|
||||||
c = getchar();
|
c = getchar();
|
||||||
goto loop;
|
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:
|
case PLUS:
|
||||||
return subseq(c,PLUS,INCBEF);
|
return subseq(c,PLUS,INCBEF);
|
||||||
|
|
||||||
|
@ -1242,7 +1266,7 @@ char ctab[128] = {
|
||||||
LETTER, SPACE, NEWLN, SPACE, SPACE, 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,
|
||||||
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,
|
LPARN, RPARN, TIMES, PLUS, COMMA, MINUS, UNKN, DIVIDE,
|
||||||
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
|
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
|
||||||
DIGIT, DIGIT, COLON, SEMI, LESS, ASSIGN, GREAT, QUEST,
|
DIGIT, DIGIT, COLON, SEMI, LESS, ASSIGN, GREAT, QUEST,
|
||||||
|
|
|
@ -8,6 +8,7 @@ cprogram {
|
||||||
"./*.h",
|
"./*.h",
|
||||||
"modules+headers",
|
"modules+headers",
|
||||||
"modules/src/alloc+lib",
|
"modules/src/alloc+lib",
|
||||||
|
"modules/src/data+lib",
|
||||||
"modules/src/em_code+lib_k",
|
"modules/src/em_code+lib_k",
|
||||||
"modules/src/em_data+lib",
|
"modules/src/em_data+lib",
|
||||||
"modules/src/em_mes+lib",
|
"modules/src/em_mes+lib",
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#error Unsupported EM_PSIZE
|
#error Unsupported EM_PSIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern FILE* input_unit;
|
||||||
extern FILE* output_unit;
|
extern FILE* output_unit;
|
||||||
|
|
||||||
|
#define END 4
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
#include "b.h"
|
#include "b.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
extern uintptr_t* bsymb_patch_table[];
|
extern uintptr_t* b_module_main[];
|
||||||
extern intptr_t i_main(intptr_t argc, const char* argv[]);
|
extern intptr_t i_main(intptr_t argc, const char* argv[]);
|
||||||
|
|
||||||
|
FILE* input_unit;
|
||||||
FILE* output_unit;
|
FILE* output_unit;
|
||||||
|
|
||||||
static intptr_t i_char(intptr_t s, intptr_t n)
|
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)
|
static intptr_t i_getchar(void)
|
||||||
{
|
{
|
||||||
return fgetc(output_unit);
|
return fgetc(input_unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static intptr_t i_putchar(intptr_t c)
|
static intptr_t i_putchar(intptr_t c)
|
||||||
|
@ -28,17 +32,139 @@ static intptr_t i_putchar(intptr_t c)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static intptr_t i_putstr(intptr_t s)
|
||||||
|
{
|
||||||
|
char* p = (char*)(s<<SHIFT);
|
||||||
|
char c;
|
||||||
|
|
||||||
|
while ((c = *p++) != END)
|
||||||
|
fputc(c, output_unit);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static intptr_t i_getstr(intptr_t s)
|
||||||
|
{
|
||||||
|
char* p = (char*)(s<<SHIFT);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int c = fgetc(input_unit);
|
||||||
|
if ((c == -1) || (c == '\n'))
|
||||||
|
break;
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p++ = END;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i_flush(void)
|
||||||
|
{
|
||||||
|
fflush(output_unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tochar(int n)
|
||||||
|
{
|
||||||
|
if (n <= 9)
|
||||||
|
return n + '0';
|
||||||
|
return n - 10 + 'a';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void putnum(intptr_t value, int base)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char s[32];
|
||||||
|
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
fputc('-', output_unit);
|
||||||
|
value = -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
do
|
||||||
|
s[i++] = tochar(value % base);
|
||||||
|
while ((value /= base) > 0);
|
||||||
|
|
||||||
|
do
|
||||||
|
fputc(s[--i], output_unit);
|
||||||
|
while (i > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i_printf(intptr_t s, ...)
|
||||||
|
{
|
||||||
|
char* p = (char*)(s<<SHIFT);
|
||||||
|
char c;
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, s);
|
||||||
|
|
||||||
|
while ((c = *p++) != END)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '%':
|
||||||
|
{
|
||||||
|
intptr_t ss = va_arg(ap, intptr_t);
|
||||||
|
|
||||||
|
switch ((c = *p++))
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
i_putstr(ss);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
putnum(ss, 10);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
putnum(ss, 8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
putnum(ss, 16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
fputc(ss, output_unit);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fputc('?', output_unit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
fputc(c, output_unit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t b_char = (uintptr_t)i_char;
|
uintptr_t b_char = (uintptr_t)i_char;
|
||||||
uintptr_t b_lchar = (uintptr_t)i_lchar;
|
uintptr_t b_lchar = (uintptr_t)i_lchar;
|
||||||
uintptr_t b_getchar = (uintptr_t)i_getchar;
|
uintptr_t b_getchar = (uintptr_t)i_getchar;
|
||||||
uintptr_t b_putchar = (uintptr_t)i_putchar;
|
uintptr_t b_putchar = (uintptr_t)i_putchar;
|
||||||
|
uintptr_t b_putstr = (uintptr_t)i_putstr;
|
||||||
|
uintptr_t b_getstr = (uintptr_t)i_getstr;
|
||||||
|
uintptr_t b_flush = (uintptr_t)i_flush;
|
||||||
|
uintptr_t b_printf = (uintptr_t)i_printf;
|
||||||
|
|
||||||
static uintptr_t* lib_patch_table[] =
|
static uintptr_t* b_module_stdlib[] =
|
||||||
{
|
{
|
||||||
&b_char,
|
&b_char,
|
||||||
&b_lchar,
|
&b_lchar,
|
||||||
&b_getchar,
|
&b_getchar,
|
||||||
&b_putchar,
|
&b_putchar,
|
||||||
|
&b_putstr,
|
||||||
|
&b_getstr,
|
||||||
|
&b_flush,
|
||||||
|
&b_printf,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,8 +179,9 @@ static void patch_addresses(uintptr_t** p)
|
||||||
|
|
||||||
int main(int argc, const char* argv[])
|
int main(int argc, const char* argv[])
|
||||||
{
|
{
|
||||||
patch_addresses(bsymb_patch_table);
|
patch_addresses(b_module_main);
|
||||||
patch_addresses(lib_patch_table);
|
patch_addresses(b_module_stdlib);
|
||||||
|
input_unit = stdin;
|
||||||
output_unit = stdout;
|
output_unit = stdout;
|
||||||
return i_main(argc, NULL);
|
return i_main(argc, NULL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue