Add sysflags to language parser

This commit is contained in:
David Schmenk 2014-05-18 22:31:13 -07:00
parent 1c05c27678
commit 96cb23ed57
10 changed files with 203 additions and 138 deletions

View File

@ -12,7 +12,7 @@ const xreg = 1
const yreg = 2 const yreg = 2
const preg = 3 const preg = 3
; ;
; Memory allocator screen holes. ; System flags: memory allocator screen holes.
; ;
const restxt1 = $0001 const restxt1 = $0001
const restxt2 = $0002 const restxt2 = $0002
@ -91,9 +91,9 @@ byte prefix[32] = ""
; System variable. ; System variable.
; ;
word heapsttart, heap word heapsttart, heap
word lastsym = symtbl word lastsym = symtbl
word xheap = $0400 word xheap = $0400
word sysflags = 0 word systemflags = 0
word perr word perr
word cmdptr word cmdptr
; ;
@ -882,13 +882,13 @@ def allocheap(size)
word addr word addr
addr = heap addr = heap
heap = heap + size heap = heap + size
if sysflags & reshgr1 if systemflags & reshgr1
if uword_isle(addr, $4000) and uword_isgt(heap, $2000) if uword_isle(addr, $4000) and uword_isgt(heap, $2000)
addr = $4000 addr = $4000
heap = addr + size heap = addr + size
fin fin
fin fin
if sysflags & reshgr2 if systemflags & reshgr2
if uword_isle(addr, $6000) and uword_isgt(heap, $4000) if uword_isle(addr, $6000) and uword_isgt(heap, $4000)
addr = $6000 addr = $6000
heap = addr + size heap = addr + size
@ -926,25 +926,25 @@ def allocxheap(size)
word xaddr word xaddr
xaddr = xheap xaddr = xheap
xheap = xheap + size xheap = xheap + size
if sysflags & restxt1 if systemflags & restxt1
if uword_isle(xaddr, $0800) and uword_isgt(xheap, $0400) if uword_isle(xaddr, $0800) and uword_isgt(xheap, $0400)
xaddr = $0800 xaddr = $0800
xheap = xaddr + size xheap = xaddr + size
fin fin
fin fin
if sysflags & restxt2 if systemflags & restxt2
if uword_isle(xaddr, $0C00) and uword_isgt(xheap, $0800) if uword_isle(xaddr, $0C00) and uword_isgt(xheap, $0800)
xaddr = $0C00 xaddr = $0C00
xheap = xaddr + size xheap = xaddr + size
fin fin
fin fin
if sysflags & resxhgr1 if systemflags & resxhgr1
if uword_isle(xaddr, $4000) and uword_isgt(xheap, $2000) if uword_isle(xaddr, $4000) and uword_isgt(xheap, $2000)
xaddr = $4000 xaddr = $4000
xheap = xaddr + size xheap = xaddr + size
fin fin
fin fin
if sysflags & resxhgr2 if systemflags & resxhgr2
if uword_isle(xaddr, $6000) and uword_isgt(xheap, $4000) if uword_isle(xaddr, $6000) and uword_isgt(xheap, $4000)
xaddr = $6000 xaddr = $6000
xheap = xaddr + size xheap = xaddr + size
@ -1067,7 +1067,7 @@ def loadmod(mod)
; ;
; This is an EXTended RELocatable (data+bytecode) module. ; This is an EXTended RELocatable (data+bytecode) module.
; ;
sysflags = header:4 | sysflags systemflags = header:4 | systemflags
defofst = header:6 defofst = header:6
defcnt = header:8 defcnt = header:8
init = header:10 init = header:10
@ -1383,15 +1383,15 @@ def execmod(modfile)
if stodci(modfile, @moddci) if stodci(modfile, @moddci)
saveheap = heap saveheap = heap
savexheap = xheap savexheap = xheap
savesym = lastsym savesym = lastsym
saveflags = sysflags saveflags = systemflags
^lastsym = 0 ^lastsym = 0
perr = loadmod(@moddci) perr = loadmod(@moddci)
sysflags = saveflags systemflags = saveflags
lastsym = savesym lastsym = savesym
xheap = savexheap xheap = savexheap
heap = saveheap heap = saveheap
fin fin
end end

View File

@ -244,7 +244,8 @@ int fixup_new(int tag, int type, int size)
* Emit assembly code. * Emit assembly code.
*/ */
#define BYTECODE_SEG 8 #define BYTECODE_SEG 8
#define INIT 16 #define INIT 16
#define SYSFLAGS 32
static int outflags = 0; static int outflags = 0;
static char *DB = ".BYTE"; static char *DB = ".BYTE";
static char *DW = ".WORD"; static char *DW = ".WORD";
@ -312,7 +313,7 @@ void emit_header(void)
printf("_SEGBEGIN%c\n", LBL); printf("_SEGBEGIN%c\n", LBL);
printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW); printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW);
printf("\t%s\t$DA7E\t\t\t; MAGIC #\n", DW); printf("\t%s\t$DA7E\t\t\t; MAGIC #\n", DW);
printf("\t%s\t0\t\t\t; SYSTEM FLAGS\n", DW); printf("\t%s\t_SYSFLAGS\t\t\t; SYSTEM FLAGS\n", DW);
printf("\t%s\t_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\n", DW); printf("\t%s\t_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\n", DW);
printf("\t%s\t_DEFCNT\t\t\t; BYTECODE DEF COUNT\n", DW); printf("\t%s\t_DEFCNT\t\t\t; BYTECODE DEF COUNT\n", DW);
printf("\t%s\t_INIT\t\t\t; MODULE INITIALIZATION ROUTINE\n", DW); printf("\t%s\t_INIT\t\t\t; MODULE INITIALIZATION ROUTINE\n", DW);
@ -385,6 +386,8 @@ void emit_trailer(void)
emit_bytecode_seg(); emit_bytecode_seg();
if (!(outflags & INIT)) if (!(outflags & INIT))
printf("_INIT\t=\t0\n"); printf("_INIT\t=\t0\n");
if (!(outflags & SYSFLAGS))
printf("_SYSFLAGS\t=\t0\n");
if (outflags & MODULE) if (outflags & MODULE)
{ {
printf("_DEFCNT\t=\t%d\n", defs); printf("_DEFCNT\t=\t%d\n", defs);
@ -400,6 +403,11 @@ void emit_moddep(char *name, int len)
else else
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB); printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
} }
void emit_sysflags(int val)
{
printf("_SYSFLAGS\t=\t$%04X\t\t; SYSTEM FLAGS\n", val);
outflags |= SYSFLAGS;
}
void emit_bytecode_seg(void) void emit_bytecode_seg(void)
{ {
if ((outflags & MODULE) && !(outflags & BYTECODE_SEG)) if ((outflags & MODULE) && !(outflags & BYTECODE_SEG))

View File

@ -4,6 +4,7 @@ void emit_flags(int flags);
void emit_header(void); void emit_header(void);
void emit_trailer(void); void emit_trailer(void);
void emit_moddep(char *name, int len); void emit_moddep(char *name, int len);
void emit_sysflags(int val);
void emit_bytecode_seg(void); void emit_bytecode_seg(void);
void emit_comment(char *s); void emit_comment(char *s);
void emit_asm(char *s); void emit_asm(char *s);

21
PLASMA/src/hgr1.pla Normal file
View File

@ -0,0 +1,21 @@
import STDLIB
predef memset
;
; System flags: memory allocator screen holes.
;
const restxt1 = $0001
const restxt2 = $0002
const reshgr1 = $0004
const reshgr2 = $0008
const resxhgr1 = $0010
const resxhgr2 = $0020
end
sysflags reshgr1 ; Reserve HGR page 1
memset($2000, $2000, 0) ; Clear HGR page 1
^$C054
^$C052
^$C057
^$C050
done

16
PLASMA/src/hgr1test.pla Normal file
View File

@ -0,0 +1,16 @@
import STDLIB
predef memset, memcpy, cin
end
import HGR1
end
byte i = 0
word hcolor[] = $0000, $552A, $2A55, $7F7F, $8080, $D5AA, $AAD5, $FFFF
repeat
memset($2000, $2000, hcolor[i])
i = (i + 1) & 7
until ^$C000 >= 128
^$C010
^$C054
^$C051
done

View File

@ -22,35 +22,35 @@ t_token keywords[] = {
ENDCASE_TOKEN, 'W', 'E', 'N', 'D', ENDCASE_TOKEN, 'W', 'E', 'N', 'D',
FOR_TOKEN, 'F', 'O', 'R', FOR_TOKEN, 'F', 'O', 'R',
TO_TOKEN, 'T', 'O', TO_TOKEN, 'T', 'O',
DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O', DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O',
STEP_TOKEN, 'S', 'T', 'E', 'P', STEP_TOKEN, 'S', 'T', 'E', 'P',
NEXT_TOKEN, 'N', 'E', 'X', 'T', NEXT_TOKEN, 'N', 'E', 'X', 'T',
REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T', REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T',
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L', UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K', BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
ASM_TOKEN, 'A', 'S', 'M', ASM_TOKEN, 'A', 'S', 'M',
DEF_TOKEN, 'D', 'E', 'F', DEF_TOKEN, 'D', 'E', 'F',
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T', EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T', IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N', RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
END_TOKEN, 'E', 'N', 'D', END_TOKEN, 'E', 'N', 'D',
START_TOKEN, 'S', 'T', 'A', 'R', 'T',
EXIT_TOKEN, 'E', 'X', 'I', 'T', EXIT_TOKEN, 'E', 'X', 'I', 'T',
DONE_TOKEN, 'D', 'O', 'N', 'E', DONE_TOKEN, 'D', 'O', 'N', 'E',
LOGIC_NOT_TOKEN, 'N', 'O', 'T', LOGIC_NOT_TOKEN, 'N', 'O', 'T',
LOGIC_AND_TOKEN, 'A', 'N', 'D', LOGIC_AND_TOKEN, 'A', 'N', 'D',
LOGIC_OR_TOKEN, 'O', 'R', LOGIC_OR_TOKEN, 'O', 'R',
BYTE_TOKEN, 'B', 'Y', 'T', 'E', BYTE_TOKEN, 'B', 'Y', 'T', 'E',
WORD_TOKEN, 'W', 'O', 'R', 'D', WORD_TOKEN, 'W', 'O', 'R', 'D',
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T', CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F', PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F',
SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S',
EOL_TOKEN EOL_TOKEN
}; };
void parse_error(char *errormsg) void parse_error(char *errormsg)
{ {
char *error_carrot = statement; char *error_carrot = statement;
fprintf(stderr, "\n%4d: %s\n ", lineno, statement); fprintf(stderr, "\n%4d: %s\n ", lineno, statement);
for (error_carrot = statement; error_carrot != tokenstr; error_carrot++) for (error_carrot = statement; error_carrot != tokenstr; error_carrot++)
putc(*error_carrot == '\t' ? '\t' : ' ', stderr); putc(*error_carrot == '\t' ? '\t' : ' ', stderr);
@ -59,79 +59,79 @@ void parse_error(char *errormsg)
} }
t_token scan(void) t_token scan(void)
{ {
prevtoken = scantoken; prevtoken = scantoken;
/* /*
* Skip whitespace. * Skip whitespace.
*/ */
while (*scanpos && (*scanpos == ' ' || *scanpos == '\t')) scanpos++; while (*scanpos && (*scanpos == ' ' || *scanpos == '\t')) scanpos++;
tokenstr = scanpos; tokenstr = scanpos;
/* /*
* Scan for token based on first character. * Scan for token based on first character.
*/ */
if (*scanpos == '\0' || *scanpos == '\n' || *scanpos == ';') if (*scanpos == '\0' || *scanpos == '\n' || *scanpos == ';')
scantoken = EOL_TOKEN; scantoken = EOL_TOKEN;
else if ((scanpos[0] >= 'a' && scanpos[0] <= 'z') else if ((scanpos[0] >= 'a' && scanpos[0] <= 'z')
|| (scanpos[0] >= 'A' && scanpos[0] <= 'Z') || (scanpos[0] >= 'A' && scanpos[0] <= 'Z')
|| (scanpos[0] == '_')) || (scanpos[0] == '_'))
{ {
/* /*
* ID, either variable name or reserved word. * ID, either variable name or reserved word.
*/ */
int keypos = 0, matchpos = 0; int keypos = 0, matchpos = 0;
do do
{ {
scanpos++; scanpos++;
} }
while ((*scanpos >= 'a' && *scanpos <= 'z') while ((*scanpos >= 'a' && *scanpos <= 'z')
|| (*scanpos >= 'A' && *scanpos <= 'Z') || (*scanpos >= 'A' && *scanpos <= 'Z')
|| (*scanpos == '_') || (*scanpos == '_')
|| (*scanpos >= '0' && *scanpos <= '9')); || (*scanpos >= '0' && *scanpos <= '9'));
scantoken = ID_TOKEN; scantoken = ID_TOKEN;
tokenlen = scanpos - tokenstr; tokenlen = scanpos - tokenstr;
/* /*
* Search for matching keyword. * Search for matching keyword.
*/ */
while (keywords[keypos] != EOL_TOKEN) while (keywords[keypos] != EOL_TOKEN)
{ {
while (keywords[keypos + 1 + matchpos] == toupper(tokenstr[matchpos])) while (keywords[keypos + 1 + matchpos] == toupper(tokenstr[matchpos]))
matchpos++; matchpos++;
if (IS_TOKEN(keywords[keypos + 1 + matchpos]) && (matchpos == tokenlen)) if (IS_TOKEN(keywords[keypos + 1 + matchpos]) && (matchpos == tokenlen))
{ {
/* /*
* A match. * A match.
*/ */
scantoken = keywords[keypos]; scantoken = keywords[keypos];
break; break;
} }
else else
{ {
/* /*
* Find next keyword. * Find next keyword.
*/ */
keypos += matchpos + 1; keypos += matchpos + 1;
matchpos = 0; matchpos = 0;
while (!IS_TOKEN(keywords[keypos])) keypos++; while (!IS_TOKEN(keywords[keypos])) keypos++;
} }
} }
} }
else if (scanpos[0] >= '0' && scanpos[0] <= '9') else if (scanpos[0] >= '0' && scanpos[0] <= '9')
{ {
/* /*
* Number constant. * Number constant.
*/ */
for (constval = 0; *scanpos >= '0' && *scanpos <= '9'; scanpos++) for (constval = 0; *scanpos >= '0' && *scanpos <= '9'; scanpos++)
constval = constval * 10 + *scanpos - '0'; constval = constval * 10 + *scanpos - '0';
scantoken = INT_TOKEN; scantoken = INT_TOKEN;
} }
else if (scanpos[0] == '$') else if (scanpos[0] == '$')
{ {
/* /*
* Hexadecimal constant. * Hexadecimal constant.
*/ */
constval = 0; constval = 0;
while (scanpos++) while (scanpos++)
{ {
if (*scanpos >= '0' && *scanpos <= '9') if (*scanpos >= '0' && *scanpos <= '9')
constval = constval * 16 + *scanpos - '0'; constval = constval * 16 + *scanpos - '0';
else if (*scanpos >= 'A' && *scanpos <= 'F') else if (*scanpos >= 'A' && *scanpos <= 'F')
@ -141,16 +141,16 @@ t_token scan(void)
else else
break; break;
} }
scantoken = INT_TOKEN; scantoken = INT_TOKEN;
} }
else if (scanpos[0] == '\'') else if (scanpos[0] == '\'')
{ {
/* /*
* Character constant. * Character constant.
*/ */
scantoken = CHAR_TOKEN; scantoken = CHAR_TOKEN;
if (scanpos[1] != '\\') if (scanpos[1] != '\\')
{ {
constval = scanpos[1]; constval = scanpos[1];
if (scanpos[2] != '\'') if (scanpos[2] != '\'')
{ {
@ -192,16 +192,16 @@ t_token scan(void)
} }
scanpos += 4; scanpos += 4;
} }
} }
else if (scanpos[0] == '\"') else if (scanpos[0] == '\"')
{ {
char *scanshift; char *scanshift;
/* /*
* String constant. * String constant.
*/ */
scantoken = STRING_TOKEN; scantoken = STRING_TOKEN;
constval = (long)++scanpos; constval = (long)++scanpos;
while (*scanpos && *scanpos != '\"') while (*scanpos && *scanpos != '\"')
{ {
if (*scanpos == '\\') if (*scanpos == '\\')
{ {
@ -235,13 +235,13 @@ t_token scan(void)
else else
scanpos++; scanpos++;
} }
if (!*scanpos++) if (!*scanpos++)
{ {
parse_error("Unterminated string"); parse_error("Unterminated string");
return (-1); return (-1);
} }
} }
else else
{ {
/* /*
* Potential two and three character tokens. * Potential two and three character tokens.
@ -330,8 +330,8 @@ t_token scan(void)
scantoken = TOKEN(*scanpos++); scantoken = TOKEN(*scanpos++);
} }
} }
tokenlen = scanpos - tokenstr; tokenlen = scanpos - tokenstr;
return (scantoken); return (scantoken);
} }
void scan_rewind(char *backptr) void scan_rewind(char *backptr)
{ {
@ -341,8 +341,8 @@ int scan_lookahead(void)
{ {
char *backpos = scanpos; char *backpos = scanpos;
char *backstr = tokenstr; char *backstr = tokenstr;
int prevtoken = scantoken; int prevtoken = scantoken;
int prevlen = tokenlen; int prevlen = tokenlen;
int look = scan(); int look = scan();
scanpos = backpos; scanpos = backpos;
tokenstr = backstr; tokenstr = backstr;

View File

@ -65,3 +65,9 @@ hello: hello.pla $(PLVM) $(PLASM)
ROD.REL: rod.pla $(PLVM) $(PLASM) ROD.REL: rod.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < rod.pla > rod.a ./$(PLASM) -AM < rod.pla > rod.a
acme --setpc 4096 -o ROD.REL rod.a acme --setpc 4096 -o ROD.REL rod.a
HGR1: hgr1.pla hgr1test.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < hgr1test.pla > hgr1test.a
acme --setpc 4096 -o HGR1TEST.REL hgr1test.a
./$(PLASM) -AM < hgr1.pla > hgr1.a
acme --setpc 4096 -o HGR1 hgr1.a

View File

@ -1024,6 +1024,19 @@ int parse_vars(int type)
switch (scantoken) switch (scantoken)
{ {
case SYSFLAGS_TOKEN:
if (type & (EXTERN_TYPE | LOCAL_TYPE))
{
parse_error("sysflags must be global");
return (0);
}
if (!parse_constexpr(&value, &size))
{
parse_error("Bad constant");
return (0);
}
emit_sysflags(value);
break;
case CONST_TOKEN: case CONST_TOKEN:
if (scan() != ID_TOKEN) if (scan() != ID_TOKEN)
{ {
@ -1113,7 +1126,7 @@ int parse_vars(int type)
} }
return (1); return (1);
} }
int parse_imps(void) int parse_mods(void)
{ {
if (scantoken == IMPORT_TOKEN) if (scantoken == IMPORT_TOKEN)
{ {
@ -1306,7 +1319,7 @@ int parse_module(void)
emit_header(); emit_header();
if (next_line()) if (next_line())
{ {
while (parse_imps()) next_line(); while (parse_mods()) next_line();
while (parse_vars(GLOBAL_TYPE)) next_line(); while (parse_vars(GLOBAL_TYPE)) next_line();
while (parse_defs()) next_line(); while (parse_defs()) next_line();
if (scantoken != DONE_TOKEN && scantoken != EOF_TOKEN) if (scantoken != DONE_TOKEN && scantoken != EOF_TOKEN)

View File

@ -275,24 +275,24 @@ int load_mod(byte *mod)
len = read(fd, header, 128); len = read(fd, header, 128);
} }
} }
/* /*
* Alloc heap space for relocated module (data + bytecode). * Alloc heap space for relocated module (data + bytecode).
*/ */
moddep += 1; moddep += 1;
hdrlen = moddep - header; hdrlen = moddep - header;
len -= hdrlen; len -= hdrlen;
modaddr = mark_heap(); modaddr = mark_heap();
end = modaddr + len; end = modaddr + len;
/* /*
* Read in remainder of module into memory for fixups. * Read in remainder of module into memory for fixups.
*/ */
memcpy(mem_data + modaddr, moddep, len); memcpy(mem_data + modaddr, moddep, len);
while ((len = read(fd, mem_data + end, 4096)) > 0) while ((len = read(fd, mem_data + end, 4096)) > 0)
end += len; end += len;
close(fd); close(fd);
/* /*
* Apply all fixups and symbol import/export. * Apply all fixups and symbol import/export.
*/ */
modfix = modaddr - hdrlen - MOD_ADDR; modfix = modaddr - hdrlen - MOD_ADDR;
bytecode += modfix; bytecode += modfix;
end = modaddr - hdrlen + modsize; end = modaddr - hdrlen + modsize;

View File

@ -41,7 +41,7 @@
#define DONE_TOKEN TOKEN(27) #define DONE_TOKEN TOKEN(27)
#define RETURN_TOKEN TOKEN(28) #define RETURN_TOKEN TOKEN(28)
#define BREAK_TOKEN TOKEN(29) #define BREAK_TOKEN TOKEN(29)
#define START_TOKEN TOKEN(30) #define SYSFLAGS_TOKEN TOKEN(30)
#define EXIT_TOKEN TOKEN(31) #define EXIT_TOKEN TOKEN(31)
#define EVAL_TOKEN TOKEN(32) #define EVAL_TOKEN TOKEN(32)
/* /*