mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-02-03 07:34:11 +00:00
Martin Haye's include processing code
This commit is contained in:
parent
3cdb146f64
commit
4aca6e749c
10
src/makefile
10
src/makefile
@ -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
127
src/samplesrc/test.pla
Normal file → Executable 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
|
||||||
|
@ -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.
|
||||||
//
|
//
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user