diff --git a/src/makefile b/src/makefile index 16f195f..4ced631 100644 --- a/src/makefile +++ b/src/makefile @@ -90,9 +90,9 @@ $(PLVM03): vmsrc/plvm03.s vmsrc/soscmd.a # Sample code # 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 - 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 ./$(PLVM) TEST @@ -164,10 +164,6 @@ $(ROGUEMAP): samplesrc/rogue.map.pla $(PLVM02) $(PLASM) ./$(PLASM) -AM < samplesrc/rogue.map.pla > 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) ./$(PLASM) -AM < samplesrc/hgr1test.pla > 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 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 ./$(PLVM) HELLO diff --git a/src/samplesrc/test.pla b/src/samplesrc/test.pla old mode 100644 new mode 100755 index e5372d2..a31aa48 --- a/src/samplesrc/test.pla +++ b/src/samplesrc/test.pla @@ -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 - -def header(text) - puts("Before\n") - puts(text) - puts("After\n") +// +// Const expression +// +const constval = 2*(2+3) // a test expression should evaluate to 10 +// +// 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 - -header("Hello, world.\n") - -done \ No newline at end of file +def ascii + byte i + i = 32 + 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 diff --git a/src/samplesrc/testlib.pla b/src/samplesrc/testlib.pla index 6a2e829..e2d288c 100755 --- a/src/samplesrc/testlib.pla +++ b/src/samplesrc/testlib.pla @@ -1,7 +1,7 @@ // // Include all imported modules and their data/functions. // -include(cmdsys.plh) +include "inc/cmdsys.plh" // // Module data. // diff --git a/src/toolsrc/lex.c b/src/toolsrc/lex.c index d46e902..938c399 100755 --- a/src/toolsrc/lex.c +++ b/src/toolsrc/lex.c @@ -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 . + * 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 #include #include +#include #include "tokens.h" #include "symbols.h" @@ -8,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', @@ -33,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', @@ -52,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); @@ -69,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') @@ -375,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 = ""; + } if (*scanpos == ';') { statement = ++scanpos; @@ -382,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; } diff --git a/src/toolsrc/tokens.h b/src/toolsrc/tokens.h index 3313ea8..b5c81d8 100755 --- a/src/toolsrc/tokens.h +++ b/src/toolsrc/tokens.h @@ -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 . + * 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 IS_TOKEN(c) (0x80&(c)) @@ -104,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;