1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-10-18 07:24:16 +00:00

Martin Haye's include processing code

This commit is contained in:
dschmenk 2015-09-25 07:59:19 -07:00
parent 3cdb146f64
commit 4aca6e749c
5 changed files with 212 additions and 25 deletions

View File

@ -90,9 +90,9 @@ $(PLVM03): vmsrc/plvm03.s vmsrc/soscmd.a
# Sample code # Sample code
# #
test: samplesrc/test.pla samplesrc/testlib.pla $(PLVM) $(PLASM) test: samplesrc/test.pla samplesrc/testlib.pla $(PLVM) $(PLASM)
m4 -I inc < samplesrc/test.pla | ./$(PLASM) -AM > samplesrc/test.a ./$(PLASM) -AM < samplesrc/test.pla > samplesrc/test.a
acme --setpc 4094 -o $(TEST) samplesrc/test.a acme --setpc 4094 -o $(TEST) samplesrc/test.a
m4 -I inc < samplesrc/testlib.pla | ./$(PLASM) -AM > samplesrc/testlib.a ./$(PLASM) -AM < samplesrc/testlib.pla > samplesrc/testlib.a
acme --setpc 4094 -o $(TESTLIB) samplesrc/testlib.a acme --setpc 4094 -o $(TESTLIB) samplesrc/testlib.a
./$(PLVM) TEST ./$(PLVM) TEST
@ -164,10 +164,6 @@ $(ROGUEMAP): samplesrc/rogue.map.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/rogue.map.pla > samplesrc/rogue.map.a ./$(PLASM) -AM < samplesrc/rogue.map.pla > samplesrc/rogue.map.a
acme --setpc 4094 -o $(ROGUEMAP) samplesrc/rogue.map.a acme --setpc 4094 -o $(ROGUEMAP) samplesrc/rogue.map.a
$(PROFILE): samplesrc/profile.pla $(PLVM02) $(PLASM)
m4 -I inc < samplesrc/profile.pla | ./$(PLASM) -AM > samplesrc/profile.a
acme --setpc 4094 -o $(PROFILE) samplesrc/profile.a
$(HGR1): samplesrc/hgr1.pla samplesrc/hgr1test.pla $(PLVM02) $(PLASM) $(HGR1): samplesrc/hgr1.pla samplesrc/hgr1test.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/hgr1test.pla > samplesrc/hgr1test.a ./$(PLASM) -AM < samplesrc/hgr1test.pla > samplesrc/hgr1test.a
acme --setpc 4094 -o $(HGR1TEST) samplesrc/hgr1test.a acme --setpc 4094 -o $(HGR1TEST) samplesrc/hgr1test.a
@ -175,6 +171,6 @@ $(HGR1): samplesrc/hgr1.pla samplesrc/hgr1test.pla $(PLVM02) $(PLASM)
acme --setpc 4094 -o $(HGR1) samplesrc/hgr1.a acme --setpc 4094 -o $(HGR1) samplesrc/hgr1.a
hello: samplesrc/hello.pla $(PLVM) $(PLASM) hello: samplesrc/hello.pla $(PLVM) $(PLASM)
m4 -I inc < samplesrc/hello.pla | ./$(PLASM) -AM > samplesrc/hello.a ./$(PLASM) -AM > samplesrc/hello.a
acme --setpc 4094 -o $(HELLO) samplesrc/hello.a acme --setpc 4094 -o $(HELLO) samplesrc/hello.a
./$(PLVM) HELLO ./$(PLVM) HELLO

127
src/samplesrc/test.pla Normal file → Executable file
View File

@ -1,13 +1,118 @@
import cmdsys //
predef puts // Include all imported modules and their data/functions.
//
include "inc/cmdsys.plh"
include "inc/testlib.plh"
//
// Structure definition.
//
struc mystruc
byte cmd
word param
byte[3]
word data
end end
//
def header(text) // Const expression
puts("Before\n") //
puts(text) const constval = 2*(2+3) // a test expression should evaluate to 10
puts("After\n") //
// Declare all global variables for this module.
// Note that arrays are declared with prefix []. postfix [], or no [].
// Only arrays with predclared sizes need [ and ], such as "int[3] a".
//
byte[] hello = "Hello, Apple "
byte[] a1 = "1"
byte[] a2 = "]["
byte[] a2p = "][+"
byte[] a2e = "//e"
byte[] a2c = "//c"
byte[] a3 = "///"
byte constr = "Constant expression = "
byte[] offsets = "Structure offsets:"
word array[] = 1, 10, 100, 1000, 10000
word ptr
byte spaces = " "
//
// Define functions.
//
def tens(start)
word i
i = start
repeat
print:hex(i)
print:str(@spaces)
print:dec(i)
print:newln()
i = i / 10
until i == 0
end end
def ascii
header("Hello, world.\n") byte i
i = 32
done while i < 128
putc(i)
i = i + 1
loop
end
def nums(range)
word i
for i = range downto -range step range/10
puti(i)
putln
next
end
export def main(range)
nums(*range)
tens(*range*10)
ascii
putln
puts(@hello)
when MACHID & $C8
is $08
puts(@a1)
break
is $00
puts(@a2)
break
is $40
puts(@a2p)
break
is $80
puts(@a2e)
break
is $88
puts(@a2c)
break
is $C0
puts(@a3)
break
otherwise
putc('?')
wend
putln
end
ptr = @main
ptr(@array:6)
ptr = @array
puti((ptr):6)
putln
puti(ptr=>6)
putln
puti((ptr).6)
putln
puti(ptr->6)
putln
puts(@offsets)
putln
puti(cmd)
putln
puti(param)
putln
puti(data)
putln
puti(mystruc)
putln
puts(@constr); puti(constval); putln
puts("Hello from in-line string!\n")
done

View File

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

View File

@ -1,6 +1,17 @@
/*
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
* ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h>
#include "tokens.h" #include "tokens.h"
#include "symbols.h" #include "symbols.h"
@ -8,7 +19,12 @@ char *statement, *tokenstr, *scanpos = "";
t_token scantoken, prevtoken; t_token scantoken, prevtoken;
int tokenlen; int tokenlen;
long constval; long constval;
FILE* inputfile;
char *filename;
int lineno = 0; int lineno = 0;
FILE* outer_inputfile = NULL;
char* outer_filename;
int outer_lineno;
t_token keywords[] = { t_token keywords[] = {
IF_TOKEN, 'I', 'F', IF_TOKEN, 'I', 'F',
ELSE_TOKEN, 'E', 'L', 'S', 'E', ELSE_TOKEN, 'E', 'L', 'S', 'E',
@ -33,6 +49,7 @@ t_token keywords[] = {
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',
INCLUDE_TOKEN, 'I', 'N', 'C', 'L', 'U', 'D', 'E',
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',
DONE_TOKEN, 'D', 'O', 'N', 'E', DONE_TOKEN, 'D', 'O', 'N', 'E',
@ -52,7 +69,7 @@ void parse_error(char *errormsg)
{ {
char *error_carrot = statement; 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++) for (error_carrot = statement; error_carrot != tokenstr; error_carrot++)
putc(*error_carrot == '\t' ? '\t' : ' ', stderr); putc(*error_carrot == '\t' ? '\t' : ' ', stderr);
fprintf(stderr, "^\nError: %s\n", errormsg); fprintf(stderr, "^\nError: %s\n", errormsg);
@ -69,7 +86,9 @@ t_token scan(void)
/* /*
* Scan for token based on first character. * 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; 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')
@ -375,6 +394,14 @@ int scan_lookahead(void)
char inputline[512]; char inputline[512];
int next_line(void) int next_line(void)
{ {
int len;
t_token token;
char* new_filename;
if (inputfile == NULL) {
// First-time init
inputfile = stdin;
filename = "<stdin>";
}
if (*scanpos == ';') if (*scanpos == ';')
{ {
statement = ++scanpos; statement = ++scanpos;
@ -382,12 +409,61 @@ int next_line(void)
} }
else else
{ {
gets(inputline);
lineno++;
statement = inputline; statement = inputline;
scanpos = 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; 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

@ -1,3 +1,12 @@
/*
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
* ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
#define TOKEN(c) (0x80|(c)) #define TOKEN(c) (0x80|(c))
#define IS_TOKEN(c) (0x80&(c)) #define IS_TOKEN(c) (0x80&(c))
@ -104,6 +113,7 @@
#define COMMA_TOKEN TOKEN(',') #define COMMA_TOKEN TOKEN(',')
#define COMMENT_TOKEN TOKEN(';') #define COMMENT_TOKEN TOKEN(';')
#define EOL_TOKEN TOKEN(0) #define EOL_TOKEN TOKEN(0)
#define INCLUDE_TOKEN TOKEN(0x7E)
#define EOF_TOKEN TOKEN(0x7F) #define EOF_TOKEN TOKEN(0x7F)
typedef unsigned char t_token; typedef unsigned char t_token;