Added PLASMA support for single-level source code include statement, without needing m4. Usage: include "yourfile.pla"

This commit is contained in:
Martin Haye 2015-09-13 09:29:42 -07:00
parent a4e87954a3
commit fa6bdfb86d
5 changed files with 80 additions and 13 deletions

View File

@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "tokens.h"
#include "symbols.h"
@ -18,7 +19,12 @@ char *statement, *tokenstr, *scanpos = "";
t_token scantoken, prevtoken;
int tokenlen;
long constval;
FILE* inputfile;
char *filename;
int lineno = 0;
FILE* outer_inputfile = NULL;
char* outer_filename;
int outer_lineno;
t_token keywords[] = {
IF_TOKEN, 'I', 'F',
ELSE_TOKEN, 'E', 'L', 'S', 'E',
@ -43,6 +49,7 @@ t_token keywords[] = {
DEF_TOKEN, 'D', 'E', 'F',
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
INCLUDE_TOKEN, 'I', 'N', 'C', 'L', 'U', 'D', 'E',
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
END_TOKEN, 'E', 'N', 'D',
DONE_TOKEN, 'D', 'O', 'N', 'E',
@ -62,7 +69,7 @@ void parse_error(char *errormsg)
{
char *error_carrot = statement;
fprintf(stderr, "\n%4d: %s\n ", lineno, statement);
fprintf(stderr, "\n%s %4d: %s\n%*s ", filename, lineno, statement, (int)strlen(filename), "");
for (error_carrot = statement; error_carrot != tokenstr; error_carrot++)
putc(*error_carrot == '\t' ? '\t' : ' ', stderr);
fprintf(stderr, "^\nError: %s\n", errormsg);
@ -79,7 +86,9 @@ t_token scan(void)
/*
* Scan for token based on first character.
*/
if (*scanpos == '\0' || *scanpos == '\n' || *scanpos == ';')
if (scantoken == EOF_TOKEN)
;
else if (*scanpos == '\0' || *scanpos == '\n' || *scanpos == ';')
scantoken = EOL_TOKEN;
else if ((scanpos[0] >= 'a' && scanpos[0] <= 'z')
|| (scanpos[0] >= 'A' && scanpos[0] <= 'Z')
@ -385,6 +394,14 @@ int scan_lookahead(void)
char inputline[512];
int next_line(void)
{
int len;
t_token token;
char* new_filename;
if (inputfile == NULL) {
// First-time init
inputfile = stdin;
filename = "<stdin>";
}
if (*scanpos == ';')
{
statement = ++scanpos;
@ -392,12 +409,61 @@ int next_line(void)
}
else
{
gets(inputline);
lineno++;
statement = inputline;
scanpos = inputline;
// Read next line from the current file, and strip newline from the end.
if (fgets(inputline, 512, inputfile) == NULL) {
inputline[0] = 0;
// At end of file, return to previous file if any, else return EOF_TOKEN
if (outer_inputfile != NULL) {
fclose(inputfile);
free(filename);
inputfile = outer_inputfile;
filename = outer_filename;
lineno = outer_lineno - 1; // -1 because we're about to incr again
outer_inputfile = NULL;
}
else {
scantoken = EOF_TOKEN;
return EOF_TOKEN;
}
}
len = strlen(inputline);
if (len > 0 && inputline[len-1] == '\n')
inputline[len-1] = '\0';
lineno++;
scantoken = EOL_TOKEN;
printf("; %03d: %s\n", lineno, inputline);
printf("; %s: %04d: %s\n", filename, lineno, inputline);
}
return (scan());
token = scan();
// Handle single level of file inclusion
if (token == INCLUDE_TOKEN) {
token = scan();
if (token != STRING_TOKEN) {
parse_error("Missing include filename");
scantoken = EOF_TOKEN;
return EOF_TOKEN;
}
if (outer_inputfile != NULL) {
parse_error("Only one level of includes allowed");
scantoken = EOF_TOKEN;
return EOF_TOKEN;
}
outer_inputfile = inputfile;
outer_filename = filename;
outer_lineno = lineno;
new_filename = malloc(tokenlen-1);
strncpy(new_filename, (char*)constval, tokenlen-2);
new_filename[tokenlen-2] = 0;
inputfile = fopen(new_filename, "r");
if (inputfile == NULL) {
parse_error("Error opening include file");
scantoken = EOF_TOKEN;
return EOF_TOKEN;
}
filename = new_filename;
lineno = 0;
return next_line();
}
return token;
}

View File

@ -41,20 +41,20 @@ $(CMD): cmd.pla cmdstub.s $(PLVM) $(PLASM)
acme --setpc 8192 -o $(CMD) cmdstub.s
TESTLIB\#FE1000: testlib.pla $(PLVM) $(PLASM)
m4 < testlib.pla |./$(PLASM) -AM > testlib.a
./$(PLASM) -AM < testlib.pla > testlib.a
acme --setpc 4094 -o TESTLIB\#FE1000 testlib.a
test: test.pla TESTLIB\#FE1000 $(PLVM) $(PLASM)
m4 < test.pla | ./$(PLASM) -AM > test.a
./$(PLASM) -AM < test.pla > test.a
acme --setpc 4094 -o TEST\#FE1000 test.a
./$(PLVM) TEST
debug: test.pla TESTLIB $(PLVM) $(PLASM)
m4 < test.pla | ./$(PLASM) -AM > test.a
./$(PLASM) -AM < test.pla > test.a
acme --setpc 4094 -o TEST\#FE1000 test.a
./$(PLVM) -s TEST MAIN
hello: hello.pla $(PLVM) $(PLASM)
m4 < hello.pla | ./$(PLASM) -AM > hello.a
./$(PLASM) -AM < hello.pla > hello.a
acme --setpc 4094 -o HELLO\#FE1000 hello.a
./$(PLVM) HELLO

View File

@ -11,8 +11,8 @@
//
// Include all imported modules and their data/functions.
//
include(cmdsys.plh)
include(testlib.plh)
include "cmdsys.plh"
include "testlib.plh"
//
// Structure definition.
//

View File

@ -11,7 +11,7 @@
//
// Include all imported modules and their data/functions.
//
include(cmdsys.plh)
include "cmdsys.plh"
//
// Module data.
//

View File

@ -113,6 +113,7 @@
#define COMMA_TOKEN TOKEN(',')
#define COMMENT_TOKEN TOKEN(';')
#define EOL_TOKEN TOKEN(0)
#define INCLUDE_TOKEN TOKEN(0x7E)
#define EOF_TOKEN TOKEN(0x7F)
typedef unsigned char t_token;