Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
Some notes about the PL/M to C converter:
With case conversion enabled by the "ifdef" in main.c, all upper case
characters in an identifier are converted to lower case, and all lower case
characters are converted to upper case except for identifiers declared
LITERALLY, in which case the identifier is not case converted.
Dollar signs used in identifiers are discarded.
The use of the AND, OR and NOT operators are converted to &&, ||, and !
operators respectively. This should work, but conversion to &, |, and ~
may be desirable in many cases. There is no clear way to distinguish which
conversion to use, thus the previous conversions were chosen. A #define
in tokens.h allows either convention to be chosen. A more intelligent
expression parser could do a better job of determining use of these operators.
Labels are limited in scope to that defined in C. That is, use of labels is
limited to the current function. PL/M allows external labels.
The dot operator is treated the same as the @ operator (converted to a &
reference).
Constant lists of the form:
@('string', 0)
are converted to:
"string"
Constant lists of the form:
@('string')
are converted to:
's', 't', 'r', 'i', 'n', 'g'
BYTE strings of the form:
'string'
are converted to:
's', 't', 'r', 'i', 'n', 'g'
ADDRESSes and SELECTORs are not supported.
Variables declared AT in one module and EXTERNAL in another will produce
incorrect results, as the EXTERNAL declared variable will not be treated
as a pointer. For example, in module A:
PL/M code: C code:
--------------------------------- ----------------------------------
DECLARE MEMVAR BYTE AT(8000H); BYTE *memvar = (BYTE *) 0x8000;
MEMVAR = 14H; (*memvar) = 0x14;
And in module B:
PL/M code: C code:
--------------------------------- ----------------------------------
DECLARE MEMVAR BYTE EXTERNAL; BYTE memvar;
MEMVAR = 14H; memvar = 0x14;
To avoid this problem, list each AT variable used on a single line in a file
called "at_decl.cvt".
Variable declarations within a procedure with the PUBLIC attribute *probably*
should be placed prior to the procedure definition. Currently, the PUBLIC
attribute is ignored.
Variable declarations of type POINTER are treated as type void.
BASED variables are treated as a pointer to the based variable.
For example, for the following declarations, the associated C code is
generated:
PL/M code: C code:
--------------------------------- ----------------------------------
DECLARE I BYTE; BYTE i;
DECLARE ITEM_PTR POINTER; void *item_ptr;
DECLARE ITEM BASED ITEM_PTR BYTE; BYTE **item = (BYTE **) &item_ptr;
ITEM_PTR = @I; item_ptr = &i;
ITEM = 77H; (**item) = 0x77;
Care should be taken in the use of LITERALLY declared variables. Such
declarations are converted to a #define directive. With the cvt.h flag
PARSE_LITERALS defined, the converter attempts to parse the contents of
all LITERALLY declared variables as the definition for the #define
directive. With PARSE_LITERALS undefined, no parsing takes place. Thus,
for the declaration:
DECLARE MAX_COUNT LITERALLY '55H';
the code generated with PARSE_LITERALS defined is:
#define MAX_COUNT 0x55
and the code generated with PARSE_LITERALS undefined is:
#define MAX_COUNT 55H
Control directives within comments are ignored.
The procedure attribute REENTRANT is ignored. Technically, all PL/M variables
are static and could be declared as such in all but REENTRANT procedures.
This was not done, as it was deemed improbable that any problems would result.
The user should keep this fact in mind though. Especially in cases where the
C compiler warns about using a variable before it has been defined.
In most cases, white space (spaces, tabs, returns, line-feeds and comments)
are retained in their appropriate place. In obscure instances, white space
may be discarded for the sake of simpler code. For example, white space in
some portions of a DECLARE statement is discarded, since the structure of
a DECLARE statement is drastically converted.
Array subscripts and function calls appear to be ambiguous. The converter
keeps a symbol table of DECLARATIONS to try to correctly distinguish one from
the other.

View File

@@ -0,0 +1,31 @@
README
CAVEATS.DOC
FILES
at_decl.cvt
const.c
context.c
control.c
convert.c
cvt.h
cvt_id.h
decl_out.c
declare.c
defs.h
error.c
io.c
lit.c
main.c
makefile
makefile.ibm
mem.c
misc.h
parse.c
struct.h
test.c.out
test.plm
tkn_defs.h
tkn_ext.h
token.c
tokens.h
typedefs.c
version.c

View File

@@ -0,0 +1,37 @@
This is a PL/M to C converter. It will take most PL/M code and do a nice
job of converting it to C. It tries to be intelligent about leaving formatting
and comments intact. This version supports PL/M-286. It is something I wrote
about a year ago to convert several meg of source code, and it did a 99.5%
conversion. I was later handed some source code that it crashed on, and I
extended it to support that code too.
Please keep in mind that this may well not work for your code. It has
been tested only on a few sets of code, each following its own set of coding
standards. Also, don't expect a lot of support from me, as my interest in
PL/M is next to none. I no longer work for the employer for whom I wrote
this converter, but they have given me permission to own and post the sources.
I will, time permitting, collect bug fixes and post patches to the software.
Please mail fixes directly to me, as I may miss any posting of them. If
anyone is interested in taking over maintenance of this code, please let me
know!
The source code compiles under Unix. I've compiled it on a Sun-4, a VAX
running Ultrix, and a VAX running Mt. Xinu. At one time I had a version that
ran under MSDOS, but I can't guarantee it will now. I've included a makefile
for use with Turbo-C. You need to define IBMPC to compile it. What it could
really use is tuning for a large memory model, as in it's present state, it
can only handle small source files. It could also benefit from a good man
page.
The converter expects source code to be in "proper" format (i.e. proper
use of EXTERNAL declarations, and following of the Intel PL/M grammar as the
converter knows it.) It has some moderate error-recovery, but may well dump
core if it expects one thing and gets another.
I've included a garbage file test.plm; typeing "plm2c test.plm" should
result in a test.c file that is identical to the provided test.c.out.
See the file CAVEATS.DOC for compatibility issues.
Hope you find it useful!
Robert Ankeney
April 9, 1991
...!tektronix!bob@reed.bitnet

View File

@@ -0,0 +1,27 @@
foop(i, j)
short i, j;
{
}
float foo()
{
}
WORD bletch;
void *ptr;
farp("Hi\014\037\253\036");
farp(&foo, &bar, &bletch);
bletch = foo + foop(1, 2);
bletch = foo + foop;
ptr = (void *) &foo;
ptr = (void *) &bar;
ptr = (void *) &bletch;
foo();
bar();
(*ptr)();
(*bletch)();
(*ptr)(1, 2);

View File

@@ -0,0 +1,154 @@
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
/*
* Pointer to the current context
*/
CONTEXT *context_head;
/*
* Pointer to all popped contexts
*/
CONTEXT *old_context;
/*
* Search DECL_MEMBER list for symbol and if found, return TRUE
* and pointer to DECL_ID for that symbol.
*/
find_member_symbol(symbol, decl_ptr, decl_id)
TOKEN *symbol;
DECL_MEMBER *decl_ptr;
DECL_ID **decl_id;
{
DECL_ID *var_ptr;
for (var_ptr = decl_ptr->name_list; var_ptr;
var_ptr = var_ptr->next_var) {
if (!strcmp(var_ptr->name->token_name, symbol->token_name)) {
*decl_id = var_ptr;
return TRUE;
}
}
*decl_id = NULL;
return FALSE;
}
/*
* Search DECL_MEMBER list for symbol.
* If found, return pointer to DECL_MEMBER containing that symbol
* in decl_found, and return TRUE.
* If not found, return null pointer in decl_found, and return FALSE.
*/
find_list_symbol(symbol, decl_ptr, decl_found, decl_id)
TOKEN *symbol;
DECL_MEMBER *decl_ptr, **decl_found;
DECL_ID **decl_id;
{
for (*decl_found = decl_ptr; *decl_found;
*decl_found = (*decl_found)->next_member) {
if (find_member_symbol(symbol, *decl_found, decl_id))
return TRUE;
}
return FALSE;
}
/*
* Search context for symbol.
* If found, return pointer to DECL_MEMBER containing that symbol
* in decl_found, return DECL_ID for that symbol in decl_id, and
* return TRUE.
* If not found, return null pointers in decl_found and decl_id,
* and return FALSE.
*/
find_symbol(symbol, decl_found, decl_id)
TOKEN *symbol;
DECL_MEMBER **decl_found;
DECL_ID **decl_id;
{
CONTEXT *context_ptr;
for (context_ptr = context_head; context_ptr;
context_ptr = context_ptr->next_context) {
if (find_list_symbol(symbol, context_ptr->decl_head,
decl_found, decl_id))
return TRUE;
}
return FALSE;
}
/*
* Add a declaration to current context
*/
add_to_context(decl)
DECL_MEMBER *decl;
{
DECL_MEMBER *decl_ptr;
/* Find end of declaration list */
for (decl_ptr = decl; decl_ptr->next_member; )
decl_ptr = decl_ptr->next_member;
/* Add current declarations to tail of new list */
decl_ptr->next_member = context_head->decl_head;
context_head->decl_head = decl;
}
/*
* Add a DECL list to context and NULL the list pointer
*/
add_decl_to_context(decl)
DECL *decl;
{
DECL *decl_ptr;
/* Find end of declaration list */
for (decl_ptr = decl; decl_ptr; decl_ptr = decl_ptr->next_decl) {
if (decl_ptr->decl_list)
add_to_context(decl_ptr->decl_list);
decl_ptr->decl_list = NULL;
}
}
/*
* Push a new context of specified type and name
*/
new_context(type, name)
int type;
TOKEN *name;
{
CONTEXT *new_context;
get_context_ptr(&new_context);
new_context->context_type = type;
if (name) {
get_token_ptr(&new_context->context_name);
token_copy(name, new_context->context_name);
} else
new_context->context_name = NULL;
new_context->next_context = context_head;
context_head = new_context;
}
/*
* Pop current context and place on old context
*/
pop_context()
{
CONTEXT *popped_context;
popped_context = context_head;
context_head = popped_context->next_context;
popped_context->next_context = old_context;
old_context = popped_context;
}
/*
* Initializes context pointers
*/
init_context()
{
context_head = NULL;
old_context = NULL;
}

View File

@@ -0,0 +1,89 @@
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
#include "tokens.h"
#include "tkn_ext.h"
extern char *text_buffer;
extern char *text_ptr;
/*
* Parse a control directive.
* Handles: Abbreviation:
* $INCLUDE $IC
* $SET
* $RESET
* $IF
* $ELSE
* $ELSEIF
* $ENDIF
*/
parse_control()
{
TOKEN ctl_token, token;
int token_class;
RESERVED_WORD *word_ptr;
char include_file[128], *include_ptr;
token_class = get_token(&ctl_token);
if (token_class != IDENTIFIER) {
control_error("Invalid directive");
return;
}
for (word_ptr = &control_directives[0]; word_ptr->token != END_OF_FILE;
word_ptr++) {
if ((strlen(word_ptr->name) == ctl_token.token_length) &&
!strncmp(word_ptr->name, ctl_token.token_start,
ctl_token.token_length)) {
switch (word_ptr->token) {
case C_INCLUDE :
token_class = get_token(&token);
if (token_class != LEFT_PAREN) {
control_error("'(' expected");
return;
}
/* Copy and send file name (up to ')') */
include_ptr = include_file;
while (*text_ptr != ')') {
if ((*text_ptr >= 'A') && (*text_ptr <= 'Z'))
/* Convert to lower case */
*include_ptr++ = *text_ptr++ + ' ';
else
*include_ptr++ = *text_ptr++;
}
*include_ptr++ = '\0';
/* Skip ')' */
text_ptr++;
/* Parse include file */
cvt_file(include_file);
/* Convert .plm to .c */
if (strcmp(include_ptr - 5, "plm")) {
(void) strcpy(include_ptr - 5, ".c");
include_ptr -= 2;
}
out_to_start();
out_str("#include");
out_must_white(&token);
out_char('"');
out_str(include_file);
out_char('"');
return;
default :
control_error("Non-supported directive");
return;
}
}
}
control_error("Invalid directive");
}

View File

@@ -0,0 +1,145 @@
#include <stdio.h>
#ifdef IBMPC
#include <stdlib.h>
#endif
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
#include "tokens.h"
BOOLEAN syntax_error;
extern char *text_buffer, *text_ptr;
extern int line_count;
/*
* Determine statement type and call appropriate parse routine.
* Return statement class or, if a reserved word, reserved word token.
*/
parse_statement(first_token)
TOKEN *first_token;
{
int token_type;
/* Flush standard output and standard error */
(void) fflush(stdout);
(void) fflush(stderr);
/* Flag no error yet */
syntax_error = FALSE;
switch (first_token->token_class) {
case RESERVED:
token_type = first_token->token_type;
switch (token_type) {
case DECLARE :
parse_declare(first_token);
break;
case DO :
parse_do(first_token);
break;
case IF :
parse_if(first_token);
break;
case THEN :
parse_then();
break;
case ELSE :
parse_else(first_token);
break;
case GOTO :
parse_goto(first_token);
break;
case GO :
parse_go(first_token);
break;
case CALL :
parse_call(first_token);
break;
case RETURN :
parse_return(first_token);
break;
case END :
parse_end(first_token);
break;
case DISABLE :
parse_int_ctl(first_token);
break;
case ENABLE :
parse_int_ctl(first_token);
break;
case OUTPUT :
parse_output(first_token);
break;
case OUTWORD :
parse_outword(first_token);
break;
case OUTHWORD :
parse_outhword(first_token);
break;
default :
parse_error("Illegal reserved word");
return ERROR;
}
return token_type;
case IDENTIFIER:
parse_identifier(first_token);
break;
case LABEL:
parse_label();
break;
case END_OF_LINE:
parse_eol(first_token);
break;
case END_OF_FILE:
out_white_space(first_token);
return END_OF_FILE;
default:
parse_error("Illegal statement");
return ERROR;
}
return first_token->token_class;
}
parse_new_statement()
{
TOKEN first_token;
/* Get first token on line */
(void) get_token(&first_token);
return parse_statement(&first_token);
}
parse_file()
{
while (parse_new_statement() != END_OF_FILE) ;
}

View File

@@ -0,0 +1,82 @@
/*
* Parse LITERALLY declared strings
*/
#define PARSE_LITERALS
/*
* Ignore Invalid control errors
*/
#define IGNORE_CONTROL_ERRORS
/*
* Convert lower case to upper and upper to lower in identifiers
*/
#define CONVERT_CASE
/*
* If CONVERT_TYPES defined, use the following type conversions.
*/
#define CONVERT_TYPES
/*
* Type conversions
*/
#define TYPE_BYTE "BYTE"
#define TYPE_WORD "WORD"
#define TYPE_DWORD "DWORD"
#define TYPE_INTEGER "short"
#define TYPE_REAL "float"
/*
* For initialized DATA, use this prefix.
* Probably should be "const" or "static".
*/
#define TYPE_DATA "const"
/*
* Default POINTER type.
*/
#define TYPE_POINTER "void"
/*
* Sizes of data types
*/
#define SIZE_BYTE 1
#define SIZE_WORD 2
#define SIZE_DWORD 4
/*
* Conversion operators
*/
#define AND_OP "&&"
#define OR_OP "||"
#define NOT_OP "!"
/*
#define AND_OP "&"
#define OR_OP "|"
#define NOT_OP "~"
*/
/*
#define AND_OP "AND"
#define OR_OP "OR"
#define NOT_OP "NOT"
*/
/*
* Function call equivalent to OUTPUT(port) = expr
* Becomes: FUNC_OUTPUT(port, expr)
*/
#define FUNC_OUTPUT "outportb"
/*
* Function call equivalent to OUTWORD(port) = expr
* Becomes: FUNC_OUTWORD(port, expr)
*/
#define FUNC_OUTWORD "outport"
/*
* Function call equivalent to OUTHWORD(port) = expr
* Becomes: FUNC_OUTHWORD(port, expr)
*/
#define FUNC_OUTHWORD "outporth"

View File

@@ -0,0 +1,40 @@
/*
* PL/M Cast function equivalents
*/
CVT_ID cast_functions[] = {
"float", TYPE_REAL,
"real", TYPE_REAL,
"fix", TYPE_INTEGER,
"int", TYPE_INTEGER,
"signed", TYPE_INTEGER,
"integer", TYPE_INTEGER,
"unsign", TYPE_WORD,
"word", TYPE_WORD,
"byte", TYPE_BYTE,
"dword", TYPE_DWORD,
"pointer", TYPE_POINTER,
"", ""
};
/*
* PL/M function equivalents
*/
CVT_ID cvt_functions[] = {
"size", "sizeof",
"abs", "fabs",
"iabs", "abs",
"input", "inportb",
"inword", "inport",
"setinterrupt", "signal",
"initrealmathunit", "_fpreset",
"", ""
};
/*
* PL/M identifier equivalents
*/
CVT_ID cvt_identifiers[] = {
"getrealerror", "_status87()",
"", ""
};

View File

@@ -0,0 +1,408 @@
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
#include "tokens.h"
extern char *text_ptr;
extern int at_decl_count;
extern char at_decl_list[MAX_AT_DECLS][MAX_TOKEN_LENGTH];
/*
* Output *<name> if use_parens == NULL, else (*<name>).
*/
out_pointer(name, use_parens)
TOKEN *name;
BOOLEAN use_parens;
{
/* Use parentheses? */
if (use_parens) {
/* Yes - make it (*name) */
out_str("(*");
out_token_name(name);
out_char(')');
} else {
/* No - make it *name */
out_char('*');
out_token_name(name);
}
}
/*
* Output array bound (if any)
*/
out_bound(bound)
TOKEN *bound;
{
if (bound) {
out_char('[');
out_token(bound);
out_char(']');
}
}
/*
* Output a declaration type.
*/
out_decl_type(decl_ptr)
DECL_MEMBER *decl_ptr;
{
if (decl_ptr->type->token_type != STRUCTURE) {
out_type(decl_ptr->type->token_type);
} else {
out_struct(decl_ptr->struct_list);
}
}
/*
* Output structure contents.
*/
out_struct(el_ptr)
DECL_MEMBER *el_ptr;
{
DECL_ID *var_ptr;
out_str("struct {");
while (el_ptr) {
/* Use initial white space before type */
var_ptr = el_ptr->name_list;
if (var_ptr)
out_must_white(var_ptr->name);
out_decl_type(el_ptr);
out_char(' ');
while (var_ptr) {
out_token_name(var_ptr->name);
out_bound(el_ptr->array_bound);
var_ptr = var_ptr->next_var;
if (var_ptr) {
out_char(',');
out_must_white(var_ptr->name);
}
}
if ((el_ptr = el_ptr->next_member) != NULL)
out_char(';');
}
out_char('}');
}
/*
* Output C declaration list member.
*/
out_decl_member(decl_list, decl_token)
DECL_MEMBER *decl_list;
TOKEN *decl_token;
{
int i;
TOKEN token, tmp_token;
int token_class;
int name_count;
char count_str[8];
DECL_ID *var_ptr;
char *tmp_white_start, *tmp_white_end;
char *tmp_text_ptr;
BOOLEAN typedefed, is_at;
int string_len, string_size;
char *string_ptr;
/* Output characters up to CR */
out_pre_white(decl_token);
if (decl_list->type->token_type == LABEL)
/* Ignore label declarations */
return;
var_ptr = decl_list->name_list;
if (decl_list->type->token_type == LITERALLY) {
/* Make sure we're at start of new line */
out_pre_white(var_ptr->name);
out_to_start();
/* Convert to a #define */
out_str("#define ");
out_cvt_name(var_ptr->name);
out_char(' ');
out_str(decl_list->literal);
/*
out_str("\n");
*/
return;
}
var_ptr->name->white_space_start = decl_token->white_space_start;
var_ptr->name->white_space_end = decl_token->white_space_end;
/* Swap white space between type and first identifier */
/* and eat any new_lines prior to first identifier */
tmp_white_start = decl_list->type->white_space_start;
tmp_white_end = decl_list->type->white_space_end;
while ((tmp_white_start < tmp_white_end) && (*tmp_white_start < ' '))
tmp_white_start++;
decl_list->type->white_space_start = var_ptr->name->white_space_start;
var_ptr->name->white_space_start = tmp_white_start;
decl_list->type->white_space_end = var_ptr->name->white_space_end;
var_ptr->name->white_space_end = tmp_white_end;
out_white_space(decl_list->type);
if (decl_list->attributes == EXTERNAL) {
out_str("extern ");
/* Check if declared AT in another module */
for (i = 0; i < at_decl_count; i++)
if (!strcmp(var_ptr->name->token_name, at_decl_list[i]))
/* Yes - flag as so */
var_ptr->is_ext_at = TRUE;
} else
if (decl_list->initialization == DATA) {
out_str(TYPE_DATA);
out_char(' ');
}
is_at = (decl_list->at_ptr != NULL) || var_ptr->is_ext_at;
/* Determine if a structure with an AT attribute */
typedefed = (decl_list->type->token_type == STRUCTURE) && is_at;
/* Output type */
/* Is this a structure with an AT attribute? */
if (typedefed) {
/* Yes - output typedefed structure */
out_str("typedef ");
out_struct(decl_list->struct_list);
out_must_white(var_ptr->name);
#ifdef USE_DEFINES
out_char('_');
#endif
out_cvt_name(var_ptr->name);
if (decl_list->array_bound)
out_bound(decl_list->array_bound);
out_str(";\n");
out_white_space(decl_token);
#ifdef USE_DEFINES
out_char('_');
#endif
out_cvt_name(var_ptr->name);
} else
out_decl_type(decl_list);
/* Walk through name list */
name_count = 0;
while (var_ptr) {
if (is_at) {
/* AT (<expression>) -
OK... don't panic...
we can handle this
*/
/*
* Output:
* <type> *<ident> = (<type> *) <AT expr> + name_count
*
* NOTE: BASED variables are not dealt with.
*/
out_must_white(var_ptr->name);
/* Is this an array? */
if ((decl_list->array_bound) && !typedefed)
/* Yes - output ( *<ident> ) */
out_char('(');
out_char('*');
#ifdef USE_DEFINES
/* Output case converted name */
out_cvt_name(var_ptr->name);
#else
out_token_name(var_ptr->name);
#endif
if ((decl_list->array_bound) && !typedefed) {
out_char(')');
/* Output array bound (if any) */
out_bound(decl_list->array_bound);
}
if (decl_list->attributes != EXTERNAL) {
out_str(" = (");
/* Is this a structure? */
if (decl_list->type->token_type == STRUCTURE) {
/* Yes - output structure name prefix */
#ifdef USE_DEFINES
out_char('_');
#endif
out_cvt_name(decl_list->name_list->name);
} else
out_decl_type(decl_list);
out_str(" *) ");
out_str(decl_list->at_ptr);
if (name_count) {
(void) sprintf(count_str, " + %d", name_count);
out_str(count_str);
}
}
} else {
/* Not an AT expression (whew!) */
out_must_white(var_ptr->name);
/* Is variable based? */
if (var_ptr->based_name) {
/* Yes - Output **name = */
/* (type **) &based_name */
if (decl_list->array_bound) {
/* Use (**name)[] */
out_str("(**");
out_token_name(var_ptr->name);
out_str(")[]");
} else {
out_str("**");
out_token_name(var_ptr->name);
}
out_str(" = (");
out_decl_type(decl_list);
out_str(" **) &");
out_token_name(var_ptr->based_name);
} else
if (decl_list->type->token_type == POINTER) {
/* Yes - if based on an array */
/* output (*name) else output *name */
out_pointer(var_ptr->name,
(BOOLEAN) decl_list->array_bound);
} else {
/* Output variable name */
out_token_name(var_ptr->name);
/* Output array bound (if any) */
out_bound(decl_list->array_bound);
}
}
/* Get next name */
if ((var_ptr = var_ptr->next_var) != NULL) {
out_char(',');
name_count++;
}
}
/* Check for INITIAL or DATA initializers */
if (decl_list->initialization != NONE) {
out_str(" = ");
/* Point back to initializer string */
tmp_text_ptr = text_ptr;
text_ptr = decl_list->init_ptr;
if (decl_list->array_bound) {
out_char('{');
/* Array - determine if just a single string */
switch (decl_list->type->token_type) {
case BYTE :
string_size = SIZE_BYTE;
break;
case WORD :
string_size = SIZE_WORD;
break;
case DWORD :
string_size = SIZE_DWORD;
break;
case STRUCTURE :
/*
* Oh, SH-T!! fake it!
*/
string_size = SIZE_BYTE;
break;
default :
string_size = 0;
}
if (string_size && (get_token(&token) == STRING) &&
(get_token(&tmp_token) == RIGHT_PAREN)) {
/* Single string - break up into */
/* Pieces of sizeof(<type>) size */
string_ptr = token.token_name;
string_len = token.token_length;
while (string_len) {
out_str_const(string_ptr, string_size);
if (string_size > string_len)
string_size = string_len;
string_ptr += string_size;
if (string_len -= string_size)
out_char(',');
}
} else {
/* Point back to init string */
text_ptr = decl_list->init_ptr;
do {
token_class = parse_expression(&token);
if (token_class == COMMA)
out_token(&token);
} while (token_class == COMMA);
}
out_char('}');
/* Point past init string */
text_ptr = token.token_start + token.token_length + 2;
token_class = get_token(&token);
} else {
token_class = parse_expression(&token);
}
if (token_class != RIGHT_PAREN)
parse_error("')' expected");
text_ptr = tmp_text_ptr;
}
out_char(';');
#ifdef USE_DEFINES
/* Walk through name list and check for BASED variables */
var_ptr = decl_list->name_list;
while (var_ptr) {
/* See if variable is BASED */
if (var_ptr->based_name) {
/* Make sure we're at start of new line */
out_to_start();
out_str("#define");
out_must_token(var_ptr->based_name);
out_white_space(var_ptr->name);
out_str("(*");
out_token_name(var_ptr->name);
out_str(")\n");
}
/* See if variable is AT */
if (is_at) {
/* Make sure we're at start of new line */
out_to_start();
out_str("#define");
out_must_token(var_ptr->name);
out_white_space(var_ptr->name);
out_str("(*");
out_cvt_name(var_ptr->name);
out_str(")\n");
}
var_ptr = var_ptr->next_var;
}
#endif
}
out_decl(decl)
DECL *decl;
{
DECL_MEMBER *decl_list;
while (decl) {
for (decl_list = decl->decl_list; decl_list;
decl_list = decl_list->next_member)
out_decl_member(decl_list, decl->decl_token);
decl = decl->next_decl;
}
}

View File

@@ -0,0 +1,506 @@
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
#include "tokens.h"
extern char *text_ptr;
extern char *out_string;
/*
* Routines to process DECLARE statements.
*/
/*
* Skip to closing right parenthesis
*/
find_right_paren()
{
TOKEN token;
int token_class;
int paren_count;
paren_count = 1;
do {
token_class = get_token(&token);
if (token_class == LEFT_PAREN)
paren_count++;
else
if (token_class == RIGHT_PAREN)
paren_count--;
} while (paren_count);
}
/*
* Copy an element from source to destination
*/
element_copy(src, dest)
DECL_MEMBER *src, *dest;
{
/* Don't copy name list */
dest->name_list = NULL;
/* Don't copy link */
dest->next_member = NULL;
dest->literal = src->literal;
dest->array_bound = src->array_bound;
dest->type = src->type;
dest->attributes = src->attributes;
dest->initialization = src->initialization;
dest->at_ptr = src->at_ptr;
dest->init_ptr = src->init_ptr;
if (src->struct_list)
element_copy(src->struct_list, dest->struct_list);
}
/*
* Generate a linked list of variables of the form:
* <id> [BASED <id>[.<id>]] or
* ( <id> [BASED <id>[.<id>]] [ ,<id> [BASED <id>[.<id>]] ] ... )
* Return token following variable list.
*/
get_var_list(list_ptr, sep_token)
DECL_ID **list_ptr;
TOKEN *sep_token;
{
DECL_ID *var_ptr, *last_var;
TOKEN *token;
int token_class;
BOOLEAN multi_list;
char *par_white_start, *par_white_end;
*list_ptr = NULL;
/* Get first token */
get_token_ptr(&token);
token_class = get_token(token);
/* Determine if <var> or list of ( <var> [,<var>] ... ) */
if (token_class == LEFT_PAREN) {
/* List of ( <var> [,<var>] ... ) */
multi_list = TRUE;
/* Use white space before '(' for first identifier */
par_white_start = token->white_space_start;
par_white_end = token->white_space_end;
/* Get first identifier */
token_class = get_token(token);
token->white_space_start = par_white_start;
token->white_space_end = par_white_end;
} else
/* <var> */
multi_list = FALSE;
/* Process identifier list */
last_var = NULL;
while (1) {
if (token_class != IDENTIFIER) {
parse_error("Identifier expected");
free_var_list(*list_ptr);
free((char *) token);
*list_ptr = NULL;
return ERROR;
}
/* Get a variable structure */
get_var_ptr(&var_ptr);
if (*list_ptr == NULL)
/* Point to first variable */
*list_ptr = var_ptr;
if (last_var)
last_var->next_var = var_ptr;
last_var = var_ptr;
/* Save variable name */
var_ptr->name = token;
/* Check for BASED */
token_class = get_token(sep_token);
if ((token_class == RESERVED) &&
(sep_token->token_type == BASED)) {
/* BASED <id>[ .<id> ] */
/* Get based name */
get_token_ptr(&token);
token_class = get_token(token);
if (token_class != IDENTIFIER) {
parse_error("Identifier expected");
free_var_list(*list_ptr);
free((char *) token);
*list_ptr = NULL;
return ERROR;
}
token_class = parse_simple_variable(token, sep_token);
#ifdef USE_DEFINES
/* Swap variable name with based name */
var_ptr->based_name = var_ptr->name;
var_ptr->name = token;
#else
var_ptr->based_name = token;
#endif
}
if (!multi_list)
return token_class;
if (token_class != COMMA)
break;
/* Get next variable */
get_token_ptr(&token);
token_class = get_token(token);
}
if (token_class == RIGHT_PAREN) {
/* Get next token */
token_class = get_token(sep_token);
return token_class;
} else {
parse_error("')' expected");
free_var_list(*list_ptr);
*list_ptr = NULL;
return ERROR;
}
}
/*
* Parse a structure declaration of the form:
* STRUCTURE ( <member> [ ,<member> ] ... )
* where:
* <member> ::= { <id> | ( <id> [ ,<id> ] ... ) } [ ( <numeric> ) ] <type>
*/
parse_structure(list_ptr)
DECL_MEMBER **list_ptr;
{
DECL_MEMBER *struct_ptr, *last_struct;
TOKEN token;
int token_class;
*list_ptr = NULL;
/* Get left paren */
token_class = get_token(&token);
if (token_class != LEFT_PAREN) {
parse_error("'(' expected");
return;
}
last_struct = NULL;
do {
/* Get a DECL_MEMBER structure */
get_element_ptr(&struct_ptr);
if (*list_ptr == NULL)
/* Point to first structure */
*list_ptr = struct_ptr;
if (last_struct)
last_struct->next_member = struct_ptr;
last_struct = struct_ptr;
/* Get variable list */
token_class = get_var_list(&struct_ptr->name_list, &token);
/* Get type and optional array designator */
get_token_ptr(&struct_ptr->type);
token_class = parse_type(struct_ptr, &token);
/* Get seperator */
token_class = get_token(&token);
} while (token_class == COMMA);
if (token_class != RIGHT_PAREN) {
parse_error("'(' expected");
free_decl_list(*list_ptr);
*list_ptr = NULL;
return;
}
}
/*
* Parse type and optional array designator.
* Passed initial token.
* Returns RESERVED if appropriate type found, else returns END_OF_LINE.
*/
parse_type(el_ptr, token)
DECL_MEMBER *el_ptr;
TOKEN *token;
{
TOKEN *temp_token;
int token_class;
token_class = token->token_class;
if (token_class == LEFT_PAREN) {
/* Array specifier */
/* Get numeric or '*' */
get_token_ptr(&temp_token);
token_class = get_token(temp_token);
if ((token_class == NUMERIC) ||
((token_class == OPERATOR) &&
(temp_token->token_type == TIMES))) {
if (token_class != NUMERIC)
/* array(*) specified - ignore '*' */
temp_token->token_name[0] = '\0';
/* Save array bound token */
el_ptr->array_bound = temp_token;
} else {
parse_error("Illegal array bound");
free((char *) temp_token);
return ERROR;
}
/* Get right paren */
token_class = get_token(token);
if (token_class != RIGHT_PAREN) {
parse_error("')' expected");
free((char *) temp_token);
return ERROR;
}
/* Get type */
token_class = get_token(token);
}
if ((token_class == RESERVED) && (token->token_type >= BYTE) &&
(token->token_type <= STRUCTURE)) {
/* Save type token */
token_copy(token, el_ptr->type);
if (token->token_type == STRUCTURE) {
/* Get structure list */
parse_structure(&el_ptr->struct_list);
}
return token_class;
} else {
parse_error("Illegal type");
return ERROR;
}
}
/*
* Parse a DECLARE element.
* Return token terminating DECLARE element.
*/
get_element(element, token)
DECL_MEMBER **element;
TOKEN *token;
{
DECL_MEMBER *el_ptr;
TOKEN temp_token, eof_token;
int token_class;
char *tmp_text_ptr;
char *tmp_out_string;
char *get_mem();
get_element_ptr(element);
/* Point to element */
el_ptr = *element;
/* Get name list */
token_class = get_var_list(&el_ptr->name_list, token);
/* Malloc space for type */
get_token_ptr(&el_ptr->type);
if (token_class == RESERVED)
switch (token->token_type) {
case LABEL :
/* LABEL declaration */
token_copy(token, el_ptr->type);
/* Check for PUBLIC or EXTERNAL */
token_class = get_token(token);
if ((token_class == RESERVED) &&
((token->token_type == PUBLIC) ||
(token->token_type == EXTERNAL)))
/* Indeed, who cares? */
token_class = get_token(token);
return token_class;
case LITERALLY :
token_copy(token, el_ptr->type);
/* Check for 'string' */
if (get_token(token) != STRING) {
parse_error("String expected");
free_decl_list(el_ptr);
return ERROR;
}
el_ptr->literal = get_mem(MAX_LITERAL_SIZE);
#ifdef PARSE_LITERALS
/* Parse literal string if only one token in string */
tmp_text_ptr = text_ptr;
text_ptr = token->token_name;
/* Parse token in string */
if (get_token(&temp_token) == END_OF_FILE)
el_ptr->literal[0] = '\0';
else
if (get_token(&eof_token) == END_OF_FILE) {
/* Single token literal */
(void) strcpy(el_ptr->literal, temp_token.token_name);
/* Save parsed token */
get_token_ptr(&el_ptr->literal_token);
token_copy(&temp_token, el_ptr->literal_token);
} else
(void) strcpy(el_ptr->literal, token->token_name);
text_ptr = tmp_text_ptr;
#else
/* Put string in literal */
(void) strcpy(el_ptr->literal, token->token_name);
#endif
/* Return following token */
token_class = get_token(token);
return token_class;
}
if (parse_type(el_ptr, token) != RESERVED) {
/* Error occurred */
free_decl_list(el_ptr);
return END_OF_LINE;
}
/* Process attribute information (if any) */
/* Check for EXTERNAL [ DATA ] */
token_class = get_token(token);
if (token_class != RESERVED)
return token_class;
if (token->token_type == EXTERNAL) {
el_ptr->attributes = EXTERNAL;
/* Check for DATA attribute */
token_class = get_token(token);
if (token_class == RESERVED) {
if (token->token_type == DATA) {
/*
* Ignore attribute
* el_ptr->initialization = DATA;
*/
token_class = get_token(token);
} else {
parse_error("Illegal attribute");
free_decl_list(el_ptr);
return ERROR;
}
}
return token_class;
} else
/* Check for PUBLIC */
if (token->token_type == PUBLIC) {
el_ptr->attributes = PUBLIC;
token_class = get_token(token);
}
if (token_class != RESERVED)
return token_class;
/* Check for AT ( <expr> ) */
if (token->token_type == AT) {
/* Check for '(' */
token_class = get_token(token);
if (token_class != LEFT_PAREN) {
parse_error("'(' expected");
free_decl_list(el_ptr);
return ERROR;
}
/* Generate a string for the AT expression */
el_ptr->at_ptr = get_mem(MAX_AT_EXPR_SIZE);
el_ptr->at_ptr[0] = '\0';
tmp_out_string = out_string;
out_string = el_ptr->at_ptr;
/* Parse the expression into at_ptr */
token_class = parse_expression(token);
if (token_class != RIGHT_PAREN) {
parse_error("')' expected");
free_decl_list(el_ptr);
return ERROR;
}
out_string = tmp_out_string;
token_class = get_token(token);
}
if (token_class != RESERVED)
return token_class;
/* Check for INITIAL or DATA ( <expr> ) */
if ((token->token_type == INITIAL) ||
(token->token_type == DATA)) {
el_ptr->initialization = token->token_type;
/* Check for '(' */
token_class = get_token(token);
if (token_class != LEFT_PAREN) {
parse_error("'(' expected");
free_decl_list(el_ptr);
return ERROR;
}
el_ptr->init_ptr = text_ptr;
/* Skip to ')' */
find_right_paren();
token_class = get_token(token);
}
return token_class;
}
/*
* Parse a DECLARE list.
* Passed a pointer to a DECL, returns with DECL filled.
*/
get_decl_list(decl)
DECL *decl;
{
DECL_MEMBER *el_ptr, *decl_ptr;
TOKEN token;
int token_class;
decl->decl_list = NULL;
decl->next_decl = NULL;
decl_ptr = NULL;
do {
/* Get a declaration element */
token_class = get_element(&el_ptr, &token);
if (decl->decl_list == NULL)
decl->decl_list = el_ptr;
/* Link previous element */
if (decl_ptr)
decl_ptr->next_member = el_ptr;
decl_ptr = el_ptr;
} while (token_class == COMMA);
}
/*
* Parse a DECLARE statement.
*/
parse_declare(first_token)
TOKEN *first_token;
{
DECL decl;
decl.decl_token = first_token;
get_decl_list(&decl);
out_decl(&decl);
add_to_context(decl.decl_list);
}

View File

@@ -0,0 +1,24 @@
/*
* Maximum number of characters in a token
*/
#define MAX_TOKEN_LENGTH 512
/*
* Maximum number of characters in an individual DO CASE statement
*/
#define MAX_CASE_STATEMENT_SIZE 10240
/*
* Maximum number of characters in an AT expression
*/
#define MAX_AT_EXPR_SIZE 128
/*
* Maximum number of characters in a literal string
*/
#define MAX_LITERAL_SIZE 512
/*
* Maximum number of identifier names in at_decl.cvt
*/
#define MAX_AT_DECLS 64

View File

@@ -0,0 +1,116 @@
#include <stdio.h>
#include <string.h>
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
#include "tokens.h"
#include "tkn_ext.h"
extern BOOLEAN syntax_error;
extern char *text_ptr;
extern int line_count;
extern char *line_ptr;
extern char current_file_name[];
/*
* parse_mesg() - Print given message, message type, and current
* line number. Skip to error_eol.
*/
parse_mesg(error_string, error_type, error_eol)
char *error_string, *error_type;
char error_eol;
{
char *err_ptr;
int i, offset;
TOKEN token;
syntax_error = TRUE;
offset = text_ptr - line_ptr - 1;
/* Find end of line */
for (err_ptr = line_ptr; (*err_ptr != '\0') &&
(*err_ptr != LF); err_ptr++) ;
if (*error_string) {
(void) fprintf(stderr, "\n%s - Parse %s: %s.\nOccurred at line %d near:\n",
current_file_name, error_type, error_string, line_count);
/* Print offending line */
(void) fwrite(line_ptr, err_ptr - line_ptr + 1, 1, stderr);
for (i = 0; i < offset; i++)
if (line_ptr[i] < ' ')
(void) fputc(line_ptr[i], stderr);
else
(void) fputc(' ', stderr);
(void) fputc('^', stderr);
if (*err_ptr == '\0')
(void) fputc(LF, stderr);
}
if (*err_ptr != '\0')
err_ptr++;
/* Skip to end-of-line */
if (error_eol == '\0')
return;
else
if (error_eol == LF) {
text_ptr = err_ptr;
line_ptr = err_ptr;
line_count++;
} else {
if (*(text_ptr - 1) != ';') {
do {
i = get_token(&token);
} while ((i != END_OF_FILE) && (i != END_OF_LINE));
}
/* Point at end of line */
text_ptr--;
}
}
/*
* parse_error() - Print given error message and current line number.
* Called when an unrecognised or unprocessable token
* appears.
*/
parse_error(error_string)
char *error_string;
{
if (syntax_error)
/* Already had an error on this line */
return;
parse_mesg(error_string, "error", END_OF_LINE);
}
/*
* Do a parse_error(), but move to END_OF_LINE, not ';'
*/
control_error(error_string)
char *error_string;
{
#ifdef IGNORE_CONTROL_ERRORS
parse_mesg("", "", LF);
#else
parse_mesg(error_string, "error", LF);
#endif
}
/*
* parse_warning - Generate a warning message
*/
parse_warning(warning_string)
char *warning_string;
{
parse_mesg(warning_string, "warning", '\0');
}

View File

@@ -0,0 +1,354 @@
#include <stdio.h>
#ifdef IBMPC
#include <stdlib.h>
#endif
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
#include "tokens.h"
char *out_string;
char last_out_ch;
char *str_shifts[] = { "0", "8", "16", "24" };
extern char *text_buffer, *text_ptr;
extern int line_count;
extern int file_depth;
extern FILE *ofd;
extern BOOLEAN parsing_literal;
extern TOKEN literal_token;
/*
* Output data of specified length.
* If out_string is not NULL, append string to out_string.
* Otherwise write string to stdout.
*/
out_data(string, length)
char *string;
int length;
{
if (length) {
if (out_string)
(void) strncat(out_string, string, length);
else
if (file_depth == 1)
#ifdef DEBUG
(void) fwrite(string, length, 1, stdout);
#else
(void) fwrite(string, length, 1, ofd);
#endif
else
return;
/* Save last character output */
last_out_ch = *(string + length - 1);
}
}
/*
* Print white space
*/
out_white_space(token)
TOKEN *token;
{
int length;
/* Compute length of white space */
length = token->white_space_end - token->white_space_start;
if (length)
out_data(token->white_space_start, length);
}
/*
* Print white space, if any. If start of white space string is not
* white, prefix with a space.
*/
out_must_white(token)
TOKEN *token;
{
if (!is_white(*(token->white_space_start)))
out_char(' ');
out_white_space(token);
}
/*
* Print all white space up first new-line (if any).
* Move white_space_start to point past first new-line.
*/
out_pre_line(token)
TOKEN *token;
{
while ((token->white_space_start < token->white_space_end) &&
(*token->white_space_start != '\n')) {
out_char(*token->white_space_start);
token->white_space_start++;
}
}
/*
* Print all white space up to but not including last new-line.
* Move white_space_start to point to last new-line.
*/
out_pre_white(token)
TOKEN *token;
{
char *ptr;
int length;
for (ptr = token->white_space_end;
(ptr > token->white_space_start) && (*(ptr - 1) != '\n') ; )
ptr--;
if (ptr == token->white_space_start)
return;
/* Compute length of white space */
length = ptr - token->white_space_start - 1;
if (length)
out_data(token->white_space_start, length);
token->white_space_start = ptr - 1;
}
/*
* Output token name
*/
out_token_name(token)
TOKEN *token;
{
if (is_a_type(token))
out_type(token->token_type);
else
out_data(token->token_name, strlen(token->token_name));
}
/*
* Output white space and token name
*/
out_token(token)
TOKEN *token;
{
out_white_space(token);
out_token_name(token);
}
/*
* Output guaranteed white space and token name
*/
out_must_token(token)
TOKEN *token;
{
out_must_white(token);
out_token_name(token);
}
/*
* Output case converted token name
*/
out_cvt_name(token)
TOKEN *token;
{
char *ptr;
for (ptr = token->token_name; *ptr; ptr++) {
if (is_a_lc_char(*ptr))
out_char(*ptr - 32);
else
if (is_a_uc_char(*ptr))
out_char(*ptr + 32);
else
out_char(*ptr);
}
}
/*
* Output string
*/
out_str(string)
char *string;
{
out_data(string, strlen(string));
}
/*
* Output character
*/
out_char(ch)
char ch;
{
out_data(&ch, 1);
}
/*
* Output new-line if not at start of line
*/
out_to_start()
{
if (last_out_ch != LF)
out_char(LF);
}
/*
* Output type
*/
out_type(type)
int type;
{
switch (type) {
case BYTE :
#ifdef CONVERT_TYPES
out_str(TYPE_BYTE);
#else
out_str("BYTE");
#endif
break;
case WORD :
#ifdef CONVERT_TYPES
out_str(TYPE_WORD);
#else
out_str("WORD");
#endif
break;
case DWORD :
#ifdef CONVERT_TYPES
out_str(TYPE_DWORD);
#else
out_str("DWORD");
#endif
break;
case INTEGER :
#ifdef CONVERT_TYPES
out_str(TYPE_INTEGER);
#else
out_str("INTEGER");
#endif
break;
case REAL :
#ifdef CONVERT_TYPES
out_str(TYPE_REAL);
#else
out_str("REAL");
#endif
break;
case POINTER :
out_str(TYPE_POINTER);
break;
default :
parse_error("Unknown type");
}
}
/*
* Initialize variables for I/O.
*/
out_init()
{
out_string = NULL;
last_out_ch = '\0';
parsing_literal = FALSE;
}
/*
* Output string constant of form 'WXYZ' in form:
* 'W' << 24 | 'X' << 16 | 'Y' << 8 | Z
* where len specifies the number of bytes in the string to output.
*/
out_str_const(str_ptr, len)
char *str_ptr;
int len;
{
while (len-- && *str_ptr) {
out_char('\'');
if (*str_ptr == '\'')
out_char('\\');
out_char(*str_ptr++);
out_char('\'');
if (len) {
out_str(" << ");
out_str(str_shifts[len]);
if (*str_ptr)
out_str(" | ");
}
}
}
/*
* Convert NUMERIC constant to octal constant
*/
cvt_octal(token, octal_string)
TOKEN *token;
char octal_string[];
{
int octal;
char ch, *ptr;
octal = 0;
octal_string[0] = '\\';
octal_string[4] = '\0';
ch = *(token->token_start + token->token_length - 1);
/* Determine base of numeric */
if (ch == 'H') {
/* Hex */
for (ptr = token->token_name + 2; *ptr; ptr++) {
octal *= 16;
if ((*ptr >= '0') && (*ptr <= '9'))
octal += *ptr - '0';
else
if ((*ptr >= 'A') && (*ptr <= 'Z'))
octal += *ptr - 'A' + 10;
else
if ((*ptr >= 'a') && (*ptr <= 'z'))
octal += *ptr - 'a' + 10;
else {
parse_error("Illegal hex character");
return;
}
}
} else
if ((ch == 'O') || (ch == 'Q')) {
/* Octal constant */
for (ptr = token->token_name + 1; *ptr; ptr++) {
octal *= 8;
if ((*ptr >= '0') && (*ptr <= '7'))
octal += *ptr - '0';
else {
parse_error("Illegal decimal character");
return;
}
}
} else {
/* Decimal constant */
for (ptr = token->token_name + 1; *ptr; ptr++) {
octal *= 10;
if ((*ptr >= '0') && (*ptr <= '9'))
octal += *ptr - '0';
else {
parse_error("Illegal decimal character");
return;
}
}
}
/* Generate octal constant */
octal_string[1] = ((octal >> 6) & 3) + '0';
octal_string[2] = ((octal >> 3) & 7) + '0';
octal_string[3] = (octal & 7) + '0';
}

View File

@@ -0,0 +1,168 @@
/*********************************************************************
*********************************************************************
** **
** **
** LITERALS **
** **
** **
** Revision History: SCO #23 (12/11/84) **
** SCO #31 (02/12/86) {SCO31.DOC} **
** SCO #33 (06/03/86) {SCO33.DOC} **
** SCO #34 (10/28/86) {SCO34.DOC} **
** SCO #36 (07/16/86) {SCO36.DOC} **
** SCO #48 (03/21/87) {SCO48.DOC} **
** **
*********************************************************************
*********************************************************************/
#define POWER_FAIL_SENSE_LATCH 0x0080
#define INTERRUPT_CONTROLLER_PORT_1 0x00C0
#define INTERRUPT_CONTROLLER_PORT_2 0x00C2
#define INSTRUCTION_WORD_1 0x13
#define INSTRUCTION_WORD_2 0x20
#define INSTRUCTION_WORD_3 0x01
#define END_OF_PARITY_INTERRUPT 0x60
#define END_OF_EXCEPTION_INTERRUPT 0x61
#define END_OF_REFRESH_INTERRUPT 0x62
#define END_OF_CYCLE_INTERRUPT 0x63
#define END_OF_SHORT_INTERRUPT 0x67
#define INTERRUPT_CONTROLLER_MASK_0 0x0F0
#define INTERRUPT_CONTROLLER_MASK_1 0x0FC
#define INTERRUPT_CONTROLLER_MASK_2 0x0F8
#define INTERRUPT_CONTROLLER_MASK_3 0x0F4
#define INTERVAL_TIMER_PORT_1 0x0D2
#define INTERVAL_TIMER_PORT_2 0x0D6
#define CONTROL_WORD 0x74
#define DATA_WORD_1 0x12
#define DATA_WORD_2 0x7A
#define CONTROL_WORD_87 0x033C
#define DPM_CONTROL_WORD_87 0x0F3C
#define BIT_CONTROL_WORD_87 0x0F3C
#define INTERFACE_1_START_CODE 0x01
#define INTERFACE_2_START_CODE 0x01
#define HCP_NORMAL 0x00
#define HCP_TEST_MODE 0x01
#define HCP_ADVANCE 0x02
#define HCP_RESET 0x03
#define HCP_ALTITUDE_HOLD_RESET 0x04
#define HCP_FAIL 0x07
#define IS =
#define VALID 0x55
#define NO_COMPUTED_DATA 0x66
#define FUNCTIONAL_TEST 0x99
#define TEST_MODE 0x0AA /*{SCO36.DOC}*/
#define FLIGHT_MODE 0x55 /*{SCO36.DOC}*/
#define POSITIVE_BIAS 0 /*{SCO31.DOC}*/
#define NEGATIVE_BIAS 1 /*{SCO31.DOC}*/
#define RESET 0x0AA
#define PASS 0x55
#define ON 0x55
#define TO_VOR 0x55
#define FROM_VOR 0x99
#define ILS 0x55 /*{SCO48.DOC}*/
#define VOR 0x0AA /*{SCO48.DOC}*/
#define INVALID 0x0AA
#define OFF 0x0AA
#define PUSHED 0x55
#define SET 0x55
#define FAIL 0x0AA
#define FAILED 0x0FF
#define VMC 4
#define IMC 5
#define CRZ 6
#define TOGA 7
#define BLANK 10
#define NEGATIVE_SIGN 11
#define ERROR_DISPLAY 0x5554
#define PFM_KEY_COUNTER 0x5555
#define PFM_TIMER 0x5556
#define COMPUTER_FAULT 0x5557
#define KEY1 5
#define KEY2 4
#define KEY3 3
#define KEY4 2
#define KEY5 1
#define KEY6 0
#define DISPLAY_GENERATOR_PORT 0x0C000
#define DISPLAY_GENERATOR_HALT_CODE 3
#define DISPLAY_GENERATOR_START_CODE 4
#define DISPLAY_HALT_ENABLE_CODE 0
#define DG_HALT 0x0005
#define LOAD_ROTATION_ANGLE 0x0007
#define LOAD_PRESENT_POSITION 0x0008
#define DRAW_VECTOR 0x0009
#define LOAD_BORDERS 0x000D
#define ZERO_DEGREE_ANGLE 0
#define NINETY_DEGREE_ANGLE 0x4000
#define NEG_NINETY_DEGREE_ANGLE 0x0C000
#define ONE_EIGHTY_DEGREE_ANGLE 0x8000
#define FIRST_HALF_OF_BUFFER 0
#define SECOND_HALF_OF_BUFFER 750
#define WINDOW_COMPARATOR_FAIL 0
#define WINDOW_COMPARATOR_PASS 7
#define TWENTY_CYCLES 20
#define FORTY_CYCLES 40
#define IOS1_CODE_CHECKSUM_ERROR 0x11 /*{SCO31.DOC}*/
#define IOS1_RAM_ERROR 0x12 /*{SCO31.DOC}*/
#define IOS1_80186_ERROR 0x13 /*{SCO31.DOC}*/
#define IOS1_8087_ERROR 0x14 /*{SCO31.DOC}*/
#define IOS1_CONVERTOR_ERROR 0x15 /*{SCO31.DOC}*/
#define IOS1_HUD_POWER_SUPPLY_ERROR 0x16 /*{SCO31.DOC}*/
#define IOS2_CODE_CHECKSUM_ERROR 0x21 /*{SCO31.DOC}*/
#define IOS2_RAM_ERROR 0x22 /*{SCO31.DOC}*/
#define IOS2_80186_ERROR 0x23 /*{SCO31.DOC}*/
#define IOS2_8087_ERROR 0x24 /*{SCO31.DOC}*/
#define IOS2_CONVERTOR_ERROR 0x25 /*{SCO31.DOC}*/
#define CLP_CODE_CHECKSUM_ERROR 0x31 /*{SCO31.DOC}*/
#define CLP_RAM_ERROR 0x32 /*{SCO31.DOC}*/
#define CLP_8086_ERROR 0x33 /*{SCO31.DOC}*/
#define CLP_8087_ERROR 0x34 /*{SCO31.DOC}*/
#define SM_CODE_CHECKSUM_ERROR 0x41 /*{SCO31.DOC}*/
#define SM_RAM_ERROR 0x42 /*{SCO31.DOC}*/
#define SM_8086_ERROR 0x43 /*{SCO31.DOC}*/
#define SM_8087_ERROR 0x44 /*{SCO31.DOC}*/
#define SYSTEM_MONITOR_INACTIVE 0x45 /*{SCO31.DOC}*/
#define DISPLAY_GENERATOR_ERROR 0x51 /*{SCO31.DOC}*/
#define SYMBOL_MISPOSITIONED_1 0x52 /*{SCO31.DOC}*/
#define OHU_VIDEO_FAIL 0x63 /*{SCO31.DOC}*/
#define OHU_HVPS_FAIL 0x64 /*{SCO31.DOC}*/
#define OHU_95_OR_30_VOLT_SUPPLY_FAIL 0x65 /*{SCO31.DOC}*/
#define SYMBOL_MISPOSITIONED_2 0x71 /*{SCO31.DOC}*/
#define WINDOW_COMPARATOR_ERROR 0x77 /*{SCO31.DOC}*/
#define DEU_VERTICAL_DEFLECTION_FAIL 0x7A /*{SCO31.DOC}*/
#define DEU_HORIZONTAL_DEFLECTION_FAIL 0x7B /*{SCO31.DOC}*/
#define DEU_DC_SUPPLY_FAIL 0x7C /*{SCO31.DOC}*/
#define DEU_BOOST_SUPPLY_FAIL 0x7D /*{SCO31.DOC}*/
#define DEU_DEFLECTION_SUPPLY_FAIL 0x7E /*{SCO31.DOC}*/
#define TEST_ERROR_DISPLAY 0x88
#define DISPLAY_GENERATOR_TEST 0x89
#define HCP_FAILURE 0x91 /*{SCO31.DOC}*/
#define RSU_FAILURE 0x0A1 /*{SCO34.DOC}*/
#define COMBINER_NOT_LOCKED 0x0B1 /*{SCO33.DOC}*/
#define EIGHTH_SECOND 3
#define ONE_SIXTH_SECOND 3
#define QUARTER_SECOND 5
#define ONE_THIRD_SECOND 6
#define HALF_SECOND 10
#define ONE_SECOND 20
#define ONE_POINT_FIVE_SECONDS 30
#define TWO_SECONDS 40
#define FIVE_SECONDS 100
#define HALF_PI 1.57079633F
#define PI 3.14159265F
#define TWO_PI 6.28318531F
#define TEN_KNOTS 16.9F
#define TEN_DEGREES 0.1745F
#define FIFTEEN_DEGREES 0.2618F
#define MAXIMUM_NUMBER 99999.9F
#define FOREVER while (1)

View File

@@ -0,0 +1,248 @@
#include <stdio.h>
#ifdef IBMPC
#include <stdlib.h>
#include <sys\stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include <fcntl.h>
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
#include "tokens.h"
#include "tkn_defs.h"
char *text_buffer, *text_ptr;
int line_count;
char *line_ptr;
char current_file_name[128];
char out_file_name[128];
int at_decl_count;
char at_decl_list[MAX_AT_DECLS][MAX_TOKEN_LENGTH];
FILE *ofd;
int file_depth;
FILE *fopen();
/*
* Get list of AT declaration variables for EXTERNAL declaration checks
*/
get_at_decl()
{
int i, fd;
char ch;
at_decl_count = 0;
if ((fd = open("at_decl.cvt", O_RDONLY)) == -1)
/* Not found */
return;
while (read(fd, &ch, 1) == 1) {
i = 0;
if (!is_a_char(ch)) {
fprintf(stderr, "Illegal identifier in line %d at_decl.cvt\n",
at_decl_count + 1);
exit(1);
}
do {
#ifdef CONVERT_CASE
if (is_a_uc_char(ch))
/* Convert to lower case */
ch += 32;
else
if (is_a_lc_char(ch))
/* Convert to upper case */
ch -= 32;
#endif
at_decl_list[at_decl_count][i++] = ch;
if (read(fd, &ch, 1) != 1) {
fprintf(stderr, "Unexpected EOF in at_decl.cvt\n");
exit(1);
}
} while ((ch != '\n') && (ch != ' '));
at_decl_list[at_decl_count++][i] = '\0';
}
}
/*
* Open specified file, init options, and parse.
*/
cvt_file(file_name)
char *file_name;
{
int fd, nr;
struct stat file_stat;
TOKEN token, fname_token, token_module, token_do;
int token_class;
char *tmp_text_buffer, *tmp_text_ptr, *tmp_line_ptr;
char *tmp_ptr;
int tmp_line_count;
char tmp_file_name[128];
char *get_mem();
/* Is this the first file? */
if (file_depth) {
/* No - save old text pointers */
tmp_text_buffer = text_buffer;
tmp_text_ptr = text_ptr;
tmp_line_ptr = line_ptr;
tmp_line_count = line_count;
(void) strcpy(tmp_file_name, current_file_name);
}
/* Save file name */
(void) strcpy(current_file_name, file_name);
/* Open file */
if ((fd = open(file_name, O_RDONLY)) == -1) {
(void) fprintf(stderr, "Cannot open input file %s", file_name);
perror("");
exit(1);
}
/* Get length */
if (fstat(fd, &file_stat)) {
perror("Cannot stat input file");
exit(1);
}
/* Allocate that much RAM */
text_buffer = get_mem((unsigned int) file_stat.st_size + 1);
/* Read file */
if ((nr = read(fd, text_buffer, (int) file_stat.st_size)) == -1) {
perror("Cannot read input file");
exit(1);
}
/* Insert End-of-file Mark */
text_buffer[nr] = '\0';
(void) close(fd);
/* Init pointers */
text_ptr = text_buffer;
line_ptr = text_ptr;
line_count = 1;
/* Init I/O */
out_init();
/* Start with initial context using file name */
(void) strcpy(fname_token.token_name, file_name);
fname_token.token_class = IDENTIFIER;
new_context(MODULE, &fname_token);
/* Is this the first file? */
if (file_depth++ == 0) {
/* Yes - open output file */
if ((ofd = fopen(out_file_name, "w")) == NULL) {
(void) fprintf(stderr, "Cannot create output file %s",
out_file_name);
exit(1);
}
/* Check for module name */
token_class = get_token(&token_module);
out_pre_white(&token_module);
tmp_ptr = token_module.token_start;
if ((token_class == IDENTIFIER) &&
/* Maybe got module name - Check for : */
(get_token(&token) == LABEL) &&
/* Check for DO; */
((get_token(&token_do) == RESERVED) &&
(token_do.token_type == DO)) &&
(get_token(&token) == END_OF_LINE)) {
/* Got module header */
out_pre_white(&token_do);
/* Parse to END [<module name>] */
parse_till_end(&token);
out_white_space(&token);
token_class = get_token(&token);
if (token_class == IDENTIFIER) {
out_pre_white(&token);
token_class = get_token(&token);
}
/* Should be at end of line */
if (token_class != END_OF_LINE) {
parse_error("';' expected");
}
/* Should be at end of file */
if (get_token(&token) != END_OF_FILE) {
parse_error("End of file expected");
}
out_white_space(&token);
} else {
out_pre_white(&token_do);
parse_warning("Module name expected");
text_ptr = tmp_ptr;
parse_file();
}
} else
parse_file();
free(text_buffer);
/* Was this the first file? */
if (--file_depth) {
/* No - restore old text pointers */
text_buffer = tmp_text_buffer;
text_ptr = tmp_text_ptr;
line_ptr = tmp_line_ptr;
line_count = tmp_line_count;
(void) strcpy(current_file_name, tmp_file_name);
} else
exit(0);
}
/*
* Open file and init options
*/
main(argc, argv)
int argc;
char *argv[];
{
int i;
char ch;
if (argc != 2) {
(void) fprintf(stderr, "usage: %s filename\n", argv[0]);
exit(1);
}
/* Search for a '.' in filename */
for (i = strlen(argv[1]) - 1; i; i--) {
ch = argv[1][i];
if ((ch == '.') || (ch == '/') || (ch == '\\'))
break;
}
if (ch != '.')
i = strlen(argv[1]);
/* Append a '.c' */
(void) strncpy(out_file_name, argv[1], i);
out_file_name[i] = '\0';
(void) strcat(out_file_name, ".c");
(void) printf("Output to: %s\n", out_file_name);
/* Get AT declaration list */
get_at_decl();
/* Init context */
init_context();
file_depth = 0;
/* Parse main file */
cvt_file(argv[1]);
}

View File

@@ -0,0 +1,83 @@
# Makefile for Unix
SRCS = convert.c \
parse.c \
declare.c \
decl_out.c \
control.c \
io.c \
token.c \
context.c \
mem.c \
error.c \
version.c \
main.c
OBJS = convert.o \
parse.o \
declare.o \
decl_out.o \
control.o \
io.o \
token.o \
context.o \
mem.o \
error.o \
version.o \
main.o
LNKS = convert parse declare decl_out control io token context mem error version main
TOKEN_HDRS = misc.h defs.h struct.h cvt.h cvt_id.h tokens.h
HDRS = $(TOKEN_HDRS) tkn_defs.h tkn_ext.h
OPTS = -c -O
plm2c: $(OBJS)
$(CC) -o plm2c $(OBJS)
convert.o: convert.c $(TOKEN_HDRS)
$(CC) $(OPTS) convert.c
parse.o: parse.c $(TOKEN_HDRS) cvt_id.h
$(CC) $(OPTS) parse.c
declare.o: declare.c $(TOKEN_HDRS)
$(CC) $(OPTS) declare.c
control.o: control.c $(TOKEN_HDRS) tkn_ext.h
$(CC) $(OPTS) control.c
decl_out.o: decl_out.c $(TOKEN_HDRS)
$(CC) $(OPTS) decl_out.c
io.o: io.c $(TOKEN_HDRS) tkn_ext.h
$(CC) $(OPTS) io.c
token.o: token.c $(TOKEN_HDRS) tkn_ext.h
$(CC) $(OPTS) token.c
context.o: context.c $(TOKEN_HDRS)
$(CC) $(OPTS) context.c
mem.o: mem.c $(TOKEN_HDRS)
$(CC) $(OPTS) mem.c
error.o: error.c $(TOKEN_HDRS)
$(CC) $(OPTS) error.c
version.o: version.c
$(CC) $(OPTS) version.c
main.o: main.c $(TOKEN_HDRS) tkn_defs.h
$(CC) $(OPTS) main.c
backup:
cp $(HDRS) Makefile bak
cp $(SRCS) bak
lint:
lint $(SRCS)
clean:
rm -f $(OBJS)

View File

@@ -0,0 +1,86 @@
# Makefile for IBM-PC MSDOS
SRCS = convert.c \
parse.c \
declare.c \
decl_out.c \
control.c \
io.c \
token.c \
context.c \
mem.c \
error.c \
version.c \
main.c
OBJS = convert.obj \
parse.obj \
declare.obj \
decl_out.obj \
control.obj \
io.obj \
token.obj \
context.obj \
mem.obj \
error.obj \
version.obj \
main.obj
LNKS = convert parse declare decl_out control io token context mem error version main
TOKEN_HDRS = misc.h defs.h struct.h cvt.h cvt_id.h tokens.h
HDRS = $(TOKEN_HDRS) tkn_defs.h tkn_ext.h
MDL = m
OPTS = -c -N -v -DIBMPC -m$(MDL)
plm2c: $(OBJS)
tlink /c /v c:\tc\lib\c0$(MDL) $(LNKS), plm2c, plm2c, c:\tc\lib\c$(MDL)
convert.obj: convert.c $(TOKEN_HDRS)
tcc $(OPTS) convert
parse.obj: parse.c $(TOKEN_HDRS) cvt_id.h
tcc $(OPTS) parse
declare.obj: declare.c $(TOKEN_HDRS)
tcc $(OPTS) declare
control.obj: control.c $(TOKEN_HDRS) tkn_ext.h
tcc $(OPTS) control
decl_out.obj: decl_out.c $(TOKEN_HDRS)
tcc $(OPTS) decl_out
io.obj: io.c $(TOKEN_HDRS) tkn_ext.h
tcc $(OPTS) io
token.obj: token.c $(TOKEN_HDRS) tkn_ext.h
tcc $(OPTS) token
context.obj: context.c $(TOKEN_HDRS)
tcc $(OPTS) context
mem.obj: mem.c $(TOKEN_HDRS)
tcc $(OPTS) mem
error.obj: error.c $(TOKEN_HDRS)
tcc $(OPTS) error
version.obj: version.c
tcc $(OPTS) version
main.obj: main.c $(TOKEN_HDRS) tkn_defs.h
tcc $(OPTS) main
backup:
cp $(HDRS) Makefile bak
cp $(SRCS) bak
floppy:
cp $(HDRS) makefile a:
cp $(SRCS) a:
lint:
lint $(SRCS)

View File

@@ -0,0 +1,196 @@
#ifdef IBMPC
#include <alloc.h>
#endif
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
/*
* Memory allocation and deallocation routines.
*/
/*
* Allocate memory
*/
char *get_mem(size)
unsigned int size;
{
char *malloc_ptr;
void *malloc();
if ((malloc_ptr = (char *)malloc(size)) == NULL) {
parse_error("Out of memory");
exit(1);
}
return malloc_ptr;
}
/*
* Generate a new context.
*/
get_context_ptr(context)
CONTEXT **context;
{
*context = (CONTEXT *) get_mem(sizeof(CONTEXT));
(*context)->decl_head = NULL;
(*context)->next_context = NULL;
}
/*
* Malloc memory for a TOKEN.
*/
get_token_ptr(token)
TOKEN **token;
{
*token = (TOKEN *) get_mem(sizeof(TOKEN));
}
/*
* Malloc memory for a DECL_ID.
*/
get_var_ptr(var)
DECL_ID **var;
{
*var = (DECL_ID *) get_mem(sizeof(DECL_ID));
(*var)->name = NULL;
(*var)->based_name = NULL;
(*var)->next_var = NULL;
(*var)->is_ext_at = FALSE;
}
/*
* Free a linked list of variables.
*/
free_var_list(list_ptr)
DECL_ID *list_ptr;
{
DECL_ID *next_ptr;
while (list_ptr) {
if (list_ptr->name)
free( (char *) list_ptr->name);
if (list_ptr->based_name)
free( (char *) list_ptr->based_name);
next_ptr = list_ptr->next_var;
free((char *) list_ptr);
list_ptr = next_ptr;
}
}
/*
* Malloc space for a DECL_MEMBER structure and return pointer.
*/
get_element_ptr(element)
DECL_MEMBER **element;
{
DECL_MEMBER *el_ptr;
/* Malloc space for element */
el_ptr = (DECL_MEMBER *) get_mem(sizeof(DECL_MEMBER));
/* Init pointers */
el_ptr->name_list = NULL;
el_ptr->literal = NULL;
#ifdef PARSE_LITERALS
el_ptr->literal_token = NULL;
#endif
el_ptr->array_bound = NULL;
el_ptr->type = NULL;
el_ptr->struct_list = NULL;
el_ptr->at_ptr = NULL;
el_ptr->init_ptr = NULL;
el_ptr->next_member = NULL;
el_ptr->attributes = NONE;
el_ptr->initialization = NONE;
*element = el_ptr;
}
/*
* Free a DECL_MEMBER list.
*/
free_decl_list(element)
DECL_MEMBER *element;
{
DECL_MEMBER *el_ptr;
while (element) {
if (element->name_list)
free_var_list(element->name_list);
if (element->literal)
free((char *) element->literal);
if (element->array_bound)
free((char *) element->array_bound);
if (element->type)
free((char *) element->type);
if (element->struct_list)
free_decl_list(element->struct_list);
if (element->at_ptr)
free(element->at_ptr);
el_ptr = element->next_member;
free((char *) element);
element = el_ptr;
}
}
/*
* Malloc space for a procedure parameter
*/
get_param_ptr(param)
PARAM_LIST **param;
{
*param = (PARAM_LIST *) get_mem(sizeof(PARAM_LIST));
(*param)->next_param = NULL;
}
/*
* Free parameter list
*/
free_param_list(param_list)
PARAM_LIST *param_list;
{
PARAM_LIST *param_ptr;
while (param_list) {
param_ptr = param_list->next_param;
free((char *) param_list);
param_list = param_ptr;
}
}
/*
* Malloc space for a DECLARE statement
*/
get_decl_ptr(decl)
DECL **decl;
{
*decl = (DECL *) get_mem(sizeof(DECL));
(*decl)->decl_list = NULL;
(*decl)->next_decl = NULL;
}
/*
* Free DECL list
*/
free_decl(decl_list)
DECL *decl_list;
{
DECL *decl_ptr;
while (decl_list) {
decl_ptr = decl_list->next_decl;
#ifdef FREE_DECL_TOKEN
if (decl_list->decl_token)
free((char *) decl_list->decl_token);
#endif
if (decl_list->decl_list)
free_decl_list(decl_list->decl_list);
free((char *) decl_list);
decl_list = decl_ptr;
}
}

View File

@@ -0,0 +1,46 @@
/*
* Miscellaneous defines
*/
typedef unsigned char BYTE;
typedef unsigned char BOOLEAN;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
/*
* White space characters
*/
#define SPACE ' '
#define TAB 9
#define CR 13
#define LF 10
/*
* Useful defines
*/
#define is_a_uc_char(char) ((char >= 'A') && (char <= 'Z'))
#define is_a_lc_char(char) ((char >= 'a') && (char <= 'z'))
#define is_a_char(char) (((char & 0x5F) >= 'A') && ((char & 0x5F) <= 'Z'))
#define is_a_digit(char) ((char >= '0') && (char <= '9'))
#define is_a_type(token) ((token->token_class == RESERVED) && \
(token->token_type >= BYTE) && (token->token_type <= REAL))
#define is_white(ch) ((ch == ' ') || (ch == TAB))
#define NONE 0
char *strcat(), *strncat(), *strcpy(), *strncpy();
#ifdef IBMPC
int sprintf();
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,131 @@
/*
* Format of a token returned by get_token().
*/
typedef struct TOKEN {
/* Class of token (see below) */
int token_class;
/* Type of token (see below) */
int token_type;
/* Converted token name (when applicable) */
char token_name[MAX_TOKEN_LENGTH];
/* Pointer to start of token in text_buffer */
char *token_start;
/* Number of characters token_start points to */
int token_length;
/* Pointer to start of white space in text_buffer */
char *white_space_start;
/* Pointer to char after end of white space in text_buffer */
char *white_space_end;
#ifdef LINKED_TOKENS
/* Pointer for use in linked list */
struct TOKEN *next_token;
#endif
} TOKEN;
/*
* Format of a procedure parameter list
*/
typedef struct PARAM_LIST {
/* Parameter name */
TOKEN param;
/* Pointer for use in linked list */
struct PARAM_LIST *next_param;
} PARAM_LIST;
/*
* Format of a variable in a DECLARE statement.
*/
typedef struct DECL_ID {
/* Variable name */
TOKEN *name;
/* BASED identifier token */
TOKEN *based_name;
/* If declared AT in another module */
BOOLEAN is_ext_at;
/* Pointer for use in linked list */
struct DECL_ID *next_var;
} DECL_ID;
/*
* Format of an element in a DECLARE statement.
*/
typedef struct DECL_MEMBER {
/* Linked list of identifiers of designated type */
DECL_ID *name_list;
/* LITERALLY string */
char *literal;
#ifdef PARSE_LITERALS
/* Parsed LITERAL token */
TOKEN *literal_token;
#endif
/* Array bound token */
TOKEN *array_bound;
/* Type of variable (INTEGER, WORD, LABEL, LITERALLY, etc.) */
TOKEN *type;
/* Attributes (NONE, EXTERNAL or PUBLIC) */
int attributes;
/* Initialization attribute (NONE, INITIAL or DATA) */
/* If PROCEDURE, DATA if has parameters */
int initialization;
/* Pointer to linked list of structure elements */
struct DECL_MEMBER *struct_list;
/* Pointer to parsed AT expression */
char *at_ptr;
/* Pointer in text_buffer to start of INITIAL/DATA values */
char *init_ptr;
/* Pointer for use in linked list */
struct DECL_MEMBER *next_member;
} DECL_MEMBER;
/*
* Format of a DECLARE statement.
*/
typedef struct DECL {
/* DECLARE token */
TOKEN *decl_token;
/* Linked list of DECL_MEMBERs */
DECL_MEMBER *decl_list;
/* Pointer for use in linked list */
struct DECL *next_decl;
} DECL;
/*
* Format of a context element
*/
typedef struct CONTEXT {
/* Type of context (MODULE, PROCEDURE or DO) */
int context_type;
/* Name of module or procedure */
TOKEN *context_name;
/* Pointer to linked list of declaration members */
DECL_MEMBER *decl_head;
/* Pointer for use in linked list */
struct CONTEXT *next_context;
} CONTEXT;
/*
* Format of a PL/M identifier equivalent
*/
typedef struct {
char *id_name, *new_id;
} CVT_ID;
/*
* Format of a PL/M reserved word
*/
typedef struct {
char *name;
int token;
} RESERVED_WORD;
/*
* Format of a PL/M reserved operator
*/
typedef struct {
char *operator;
char *cvt_operator;
int name;
} RESERVED_OPERATOR;

View File

@@ -0,0 +1,26 @@
extern farp();
slug()
{
void *ptr;
short i;
short **iptr = (short **) &ptr;
float j;
float k;
float l;
WORD mqaFOO;
DWORD fooBAR;
ptr = (void *) &i;
(**iptr) = 72;
iptfil();
setinterrput(0, farp);
signal(abs(i), (short) (i));
j = (float) ((short) (i));
} /* slug */

View File

@@ -0,0 +1,25 @@
FOO: DO;
FARP: PROCEDURE EXTERNAL;
END;
SLUG :PROCEDURE;
DECLARE PTR POINTER;
DECLARE I INTEGER;
DECLARE IPTR BASED PTR INTEGER;
DECLARE J REAL;
declare k real;
declare l REAL;
declare mqaFOO WORD;
declare FOObar DWORD;
PTR = @I;
IPTR = 72;
CALL IPTFIL;
CALL SET$INTERRPUT(0, FARP);
CALL SET$INTERRUPT(IABS(I), FIX(I));
J = FLOAT(FIX(I));
END SLUG;
END FOO;

View File

@@ -0,0 +1,191 @@
/*
* Reserved word list
*/
RESERVED_WORD reserved_words[] = {
/* Statements */
"DECLARE", DECLARE,
"DO", DO,
"END", END,
"IF", IF,
"THEN", THEN,
"ELSE", ELSE,
"GOTO", GOTO,
"GO", GO,
"CALL", CALL,
"RETURN", RETURN,
"DISABLE", DISABLE,
"ENABLE", ENABLE,
"OUTPUT", OUTPUT,
"OUTWORD", OUTWORD,
"OUTHWORD", OUTHWORD,
/* Operators */
"AND", AND,
"OR", OR,
"XOR", XOR,
"NOT", NOT,
"MOD", MOD,
"PLUS", PLUS,
"MINUS", MINUS,
/* DO options */
"CASE", CASE,
"WHILE", WHILE,
"TO", TO,
"BY", BY,
/* DECLARE types */
"BYTE", BYTE,
"WORD", WORD,
"DWORD", DWORD,
"INTEGER", INTEGER,
"REAL", REAL,
"SELECTOR", SELECTOR,
"ADDRESS", ADDRESS,
"STRUCTURE", STRUCTURE,
"LABEL", LABEL,
"POINTER", POINTER,
"BASED", BASED,
"LITERALLY", LITERALLY,
/* DECLARE options */
"DATA", DATA,
"EXTERNAL", EXTERNAL,
"INITIAL", INITIAL,
"PUBLIC", PUBLIC,
"AT", AT,
/* Misc reserved words */
"PROCEDURE", PROCEDURE,
"REENTRANT", REENTRANT,
"INTERRUPT", INTERRUPT,
/* End of list */
"", END_OF_FILE
};
/*
* Operator list
*/
RESERVED_OPERATOR reserved_operators[] = {
"+", "+", PLUS,
"-", "-", MINUS,
"*", "*", TIMES,
"/", "/", DIVIDE,
"<>", "!=", NOT_EQUAL,
"<=", "<=", LESS_EQUAL,
">=", ">=", GREATER_EQUAL,
"<", "<", LESS,
">", ">", GREATER,
"=", "=", EQUAL,
":=", "=", EQUATE,
"@", "&", AT_OP,
"", "", END_OF_FILE
};
/*
* Control directives list
*/
RESERVED_WORD control_directives[] = {
#ifdef USE_ALL_CONTROLS
"CODE", C_CODE,
"CO", C_CODE,
"NOCODE", C_NOCODE,
"NOCO", C_NOCODE,
"COND", C_COND,
"NOCOND", C_NOCOND,
"DEBUG", C_DEBUG,
"DB", C_DEBUG,
"NODEBUG", C_NODEBUG,
"NODB", C_NODEBUG,
"EJECT", C_EJECT,
"EJ", C_EJECT,
#endif
"IF", C_IF,
"ELSEIF", C_ELSEIF,
"ELSE", C_ELSE,
"ENDIF", C_ENDIF,
"INCLUDE", C_INCLUDE,
"IC", C_INCLUDE,
#ifdef USE_ALL_CONTROLS
"INTERFACE", C_INTERFACE,
"ITF", C_INTERFACE,
"LEFTMARGIN", C_LEFTMARGIN,
"LM", C_LEFTMARGIN,
"LIST", C_LIST,
"LI", C_LIST,
"NOLIST", C_NOLIST,
"NOLI", C_NOLIST,
"OBJECT", C_OBJECT,
"OJ", C_OBJECT,
"NOOBJECT", C_NOOBJECT,
"NOOJ", C_NOOBJECT,
"OPTIMIZE", C_OPTIMIZE,
"OT", C_OPTIMIZE,
"OVERFLOW", C_OVERFLOW,
"OV", C_OVERFLOW,
"NOOVERFLOW", C_NOOVERFLOW,
"NOOV", C_NOOVERFLOW,
"PAGELENGTH", C_PAGELENGTH,
"PL", C_PAGELENGTH,
"PAGEWIDTH", C_PAGEWIDTH,
"PW", C_PAGEWIDTH,
"PAGING", C_PAGING,
"PI", C_PAGING,
"NOPAGING", C_NOPAGING,
"NOPI", C_NOPAGING,
"PRINT", C_PRINT,
"PR", C_PRINT,
"NOPRINT", C_NOPRINT,
"NOPR", C_NOPRINT,
"RAM", C_RAM,
"ROM", C_ROM,
"SAVE", C_SAVE,
"SA", C_SAVE,
"RESTORE", C_RESTORE,
"RS", C_RESTORE,
#endif
"SET", C_SET,
"RESET", C_RESET,
#ifdef USE_ALL_CONTROLS
"SMALL", C_SMALL,
"SM", C_SMALL,
"COMPACT", C_COMPACT,
"CP", C_COMPACT,
"MEDIUM", C_MEDIUM,
"MD", C_MEDIUM,
"LARGE", C_LARGE,
"LA", C_LARGE,
"SUBTITLE", C_SUBTITLE,
"ST", C_SUBTITLE,
"SYMBOLS", C_SYMBOLS,
"SB", C_SYMBOLS,
"NOSYMBOLS", C_NOSYMBOLS,
"NOSB", C_NOSYMBOLS,
"TITLE", C_TITLE,
"TT", C_TITLE,
"TYPE", C_TYPE,
"TY", C_TYPE,
"NOTYPE", C_NOTYPE,
"NOTY", C_NOTYPE,
"XREF", C_XREF,
"XR", C_XREF,
"NOXREF", C_NOXREF,
"NOXR", C_NOXREF,
"INTVECTOR", C_INTVECTOR,
"IV", C_INTVECTOR,
"NOINTVECTOR", C_NOINTVECTOR,
"NOIV", C_NOINTVECTOR,
"MOD86", C_MOD86,
"MOD186", C_MOD186,
"WORD16", C_WORD16,
"W16", C_WORD16,
"WORD32", C_WORD32,
"W32", C_WORD32,
#endif
/* End of list */
"", END_OF_FILE
};

View File

@@ -0,0 +1,15 @@
/*
* Reserved word list
*/
extern RESERVED_WORD reserved_words[];
/*
* Operator list
*/
extern RESERVED_OPERATOR reserved_operators[];
/*
* Control directives list
*/
extern RESERVED_WORD control_directives[];

View File

@@ -0,0 +1,478 @@
#include <stdio.h>
#include <string.h>
#include "misc.h"
#include "defs.h"
#include "cvt.h"
#include "struct.h"
#include "tokens.h"
#include "tkn_ext.h"
BOOLEAN parsing_literal;
TOKEN literal_token, eof_token;
char *lit_text_ptr;
extern char *text_buffer, *text_ptr;
extern int line_count;
extern char *line_ptr;
extern char current_file_name[];
/*
* get_token() - Fetch a token from the buffer and return type,
* pointer and associated white space.
*/
get_token(token)
TOKEN *token;
{
RESERVED_WORD *word_ptr;
RESERVED_OPERATOR *op_ptr;
char token_ch, last_token;
char *token_name_ptr;
char *op_name;
BOOLEAN got_fraction;
BOOLEAN cvt_case;
char id[MAX_TOKEN_LENGTH], *id_ptr;
DECL_MEMBER *decl_ptr;
DECL_ID *decl_id;
int token_class;
char *cvt_ptr;
TOKEN *token_ptr;
/* Point to start of white space (if any) */
token->white_space_start = text_ptr;
token->white_space_end = text_ptr;
/* Get first character */
token_ch = *text_ptr++;
/* Check for white space */
while ((token_ch == SPACE) || (token_ch == TAB) || (token_ch == CR) ||
(token_ch == LF) || (token_ch == '$') ||
((token_ch == '/') && (*text_ptr == '*'))) {
if (token_ch == '$') {
/* Check for a control directive */
if ((text_ptr - 1 == text_buffer) ||
(*(text_ptr - 2) == '\n')) {
out_pre_white(token);
parse_control();
/* Reset start of white space */
token->white_space_start = text_ptr;
token->white_space_end = text_ptr;
} else {
parse_error("Illegal character");
return ERROR;
}
} else {
*(token->white_space_end++) = token_ch;
if (token_ch == LF) {
/* Increment input line count */
line_count++;
/* Point to start of line */
line_ptr = text_ptr;
} else
if (token_ch == '/') {
/* Comment - search to end */
/* Add '*' of comment */
token_ch = *(token->white_space_end++) = *text_ptr++;
do {
last_token = token_ch;
token_ch = *(token->white_space_end++) = *text_ptr++;
if (token_ch == LF) {
/* Increment input line count */
line_count++;
/* Point to start of line */
line_ptr = text_ptr;
}
} while ((token_ch != '/') || (last_token != '*'));
}
}
token_ch = *text_ptr++;
}
/* Point to start of current token */
token->token_start = text_ptr - 1;
/* Point to start of converted token */
token_name_ptr = token->token_name;
if (is_a_char(token_ch)) {
/* Process identifier */
#ifdef CONVERT_CASE
/* Convert identifiers starting with an */
/* upper-case character to opposite case. */
cvt_case = is_a_uc_char(token_ch);
#else
cvt_case = FALSE;
#endif
while (TRUE) {
if (is_a_char(token_ch)) {
if (cvt_case) {
if (is_a_uc_char(token_ch))
/* Convert to lower-case character */
*token_name_ptr++ = token_ch + ' ';
else
/* Convert to upper-case character */
*token_name_ptr++ = token_ch - ' ';
} else
*token_name_ptr++ = token_ch;
} else
if (is_a_digit(token_ch))
*token_name_ptr++ = token_ch;
else
if (token_ch == '_')
*token_name_ptr++ = token_ch;
else
if (token_ch == '$')
#ifdef CONVERT_DOLLAR
*token_name_ptr++ = CONVERT_DOLLAR;
#else
;
#endif
else
break;
token_ch = *text_ptr++;
}
/* Mark end of token */
text_ptr--;
token->token_length = text_ptr - token->token_start;
*token_name_ptr = '\0';
/* Get a copy of identifier */
(void) strcpy(id, token->token_name);
/* If lower-case, convert to upper case for comparison */
if (is_a_lc_char(*id)) {
for (id_ptr = id; *id_ptr; id_ptr++)
if (is_a_lc_char(*id_ptr))
*id_ptr -= ' ';
}
/* Check for reserved word */
for (word_ptr = &reserved_words[0]; word_ptr->token != END_OF_FILE;
word_ptr++)
{
if (!strcmp(word_ptr->name, id)) {
token->token_type = word_ptr->token;
/* Check for reserved operator */
switch (token->token_type) {
case AND :
op_name = AND_OP;
break;
case OR :
op_name = OR_OP;
break;
case NOT :
op_name = NOT_OP;
break;
case XOR :
op_name = "^";
break;
case MOD :
op_name = "%";
break;
case PLUS :
parse_error("Cannot convert PLUS operator");
token->token_class = token->token_type = ERROR;
return ERROR;
case MINUS :
parse_error("Cannot convert MINUS operator");
token->token_class = token->token_type = ERROR;
return ERROR;
default :
/* Must not be an operator! */
token->token_class = RESERVED;
return RESERVED;
}
/* Switch to appropriate operator */
(void) strcpy(token->token_name, op_name);
token->token_class = OPERATOR;
return OPERATOR;
}
}
/* Not a reserved word - must be an identifier */
token->token_class = token->token_type = IDENTIFIER;
/* Check for a literal */
if (!parsing_literal && find_symbol(token, &decl_ptr, &decl_id) &&
(decl_ptr->type->token_type == LITERALLY)) {
#ifdef CONVERT_CASE
/* Convert case of literal */
for (cvt_ptr = token->token_name; *cvt_ptr;
cvt_ptr++) {
if (is_a_uc_char(*cvt_ptr))
*cvt_ptr += 32;
else
if (is_a_lc_char(*cvt_ptr))
*cvt_ptr -= 32;
}
#endif
#ifdef PARSE_LITERALS
/* Yes - Has literal been parsed? */
if (decl_ptr->literal_token) {
/* Yes - return parsed literal token */
/* with token_name set to literal name */
token_ptr = decl_ptr->literal_token;
token->token_class = token_ptr->token_class;
token->token_type = token_ptr->token_type;
return token->token_class;
}
#endif
/* Is literal a single token? */
lit_text_ptr = text_ptr;
text_ptr = decl_ptr->literal;
token_class = get_token(&literal_token);
if (get_token(&eof_token) == END_OF_FILE) {
/* Yes - return single token with */
/* token_name set to literal name */
token->token_class = token_class;
token->token_type = literal_token.token_type;
text_ptr = lit_text_ptr;
parsing_literal = FALSE;
return token->token_class;
}
/* No - parse complex literal and replace */
/* Use of literal declaration */
parsing_literal = TRUE;
text_ptr = lit_text_ptr;
parse_warning("Literal expanded");
text_ptr = decl_ptr->literal;
return get_token(token);
}
return IDENTIFIER;
} else
if (is_a_digit(token_ch)) {
/* Process number */
/* Flag not a floating point number */
got_fraction = FALSE;
while (TRUE) {
if (is_a_digit(token_ch))
*token_name_ptr++ = token_ch;
else
if (token_ch == '.') {
got_fraction = TRUE;
*token_name_ptr++ = token_ch;
} else
if ((token_ch == 'E') && got_fraction) {
/* Process exponent */
*token_name_ptr++ = token_ch;
/* Signed exponent? */
if ((*text_ptr != '+') && (*text_ptr != '-')) {
/* No - default to + exponent */
*token_name_ptr++ = '+';
} else {
/* Yes - add sign */
token_ch = *text_ptr++;
*token_name_ptr++ = token_ch;
}
} else
/* Assume it's a hex char or constant designator */
if (is_a_char(token_ch))
*token_name_ptr++ = token_ch;
else
if (token_ch != '$')
break;
token_ch = *text_ptr++;
}
/* Point to last character in constant */
token_name_ptr--;
token_ch = *token_name_ptr;
if (got_fraction) {
/* Floating point - add suffix */
*++token_name_ptr = 'F';
/* Mark end of token */
*++token_name_ptr = '\0';
} else
if (token_ch == 'B') {
parse_error("Binary constant");
token->token_class = token->token_type = ERROR;
return ERROR;
} else
if ((token_ch == 'O') || (token_ch == 'Q')) {
/* Octal constant */
/* Mark end of token */
*token_name_ptr++ = '\0';
/* Move constant up 1 character */
while (token_name_ptr != token->token_name) {
*token_name_ptr = *(token_name_ptr - 1);
token_name_ptr--;
}
/* Make a C octal constant */
*token_name_ptr = '0';
} else
if (token_ch == 'H') {
/* Hex constant */
/* Mark end of token */
*token_name_ptr++ = '\0';
token_name_ptr++;
/* Move constant up 2 characters */
while (token_name_ptr != (token->token_name + 1)) {
*token_name_ptr = *(token_name_ptr - 2);
token_name_ptr--;
}
/* Make a C hex constant */
*token_name_ptr-- = 'x';
*token_name_ptr = '0';
} else
if (token_ch == 'D')
/* Decimal constant - ignore 'D' */
*token_name_ptr = '\0';
else
/* Regular constant */
*++token_name_ptr = '\0';
/* Mark end of token */
text_ptr--;
token->token_length = text_ptr - token->token_start;
token->token_class = token->token_type = NUMERIC;
return NUMERIC;
} else {
/* Check for operator */
for (op_ptr = &reserved_operators[0]; op_ptr->name != END_OF_FILE;
op_ptr++) {
token->token_length = strlen(op_ptr->operator);
if (!strncmp(text_ptr - 1, op_ptr->operator,
token->token_length)) {
/* Found operator */
/* Save converted type */
(void) strcpy(token->token_name, op_ptr->cvt_operator);
token->token_type = op_ptr->name;
/* Point past operator */
text_ptr += token->token_length - 1;
token->token_class = OPERATOR;
return OPERATOR;
}
}
/* Assume single character token */
*token_name_ptr++ = token_ch;
*token_name_ptr = '\0';
/* Mark end of token so far */
token->token_length = 1;
switch (token_ch) {
case ';' :
token->token_class = token->token_type = END_OF_LINE;
return END_OF_LINE;
case ':' :
token->token_class = token->token_type = LABEL;
return LABEL;
case ',' :
token->token_class = token->token_type = COMMA;
return COMMA;
case '.' :
token->token_class = token->token_type = PERIOD;
return PERIOD;
case '(' :
token->token_class = token->token_type = LEFT_PAREN;
return LEFT_PAREN;
case ')' :
token->token_class = token->token_type = RIGHT_PAREN;
return RIGHT_PAREN;
case '\'' :
/* String constant */
token_name_ptr--;
while (1) {
if (*text_ptr == '\'') {
if ((*(text_ptr + 1) == '\''))
text_ptr++;
else
break;
}
*token_name_ptr++ = *text_ptr++;
}
text_ptr++;
*token_name_ptr++ = '\0';
token->token_length = strlen(token->token_name);
token->token_class = token->token_type = STRING;
return STRING;
case 0:
if (parsing_literal) {
/* Done parsing literal - */
/* Switch back to text_ptr */
parsing_literal = FALSE;
text_ptr = lit_text_ptr;
return get_token(token);
}
token->token_class = token->token_type = END_OF_FILE;
return END_OF_FILE;
default:
parse_error("Illegal character");
/* Eat the evidence */
token->token_name[0] = '\0';
token->token_class = token->token_type = ERROR;
return ERROR;
}
}
}
/*
* Copy source token to destination token
*/
token_copy(src, dest)
TOKEN *src, *dest;
{
dest->token_class = src->token_class;
dest->token_type = src->token_type;
(void) strcpy(dest->token_name, src->token_name);
dest->token_start = src->token_start;
dest->token_length = src->token_length;
dest->white_space_start = src->white_space_start;
dest->white_space_end = src->white_space_end;
}

View File

@@ -0,0 +1,151 @@
/**************************
* Token classes
*************************/
#define END_OF_FILE 0
#define RESERVED 1
#define IDENTIFIER 2
#define NUMERIC 3
#define OPERATOR 4
#define STRING 5
#define LABEL 6
#define END_OF_LINE 7
#define COMMA 8
#define PERIOD 9
#define LEFT_PAREN 10
#define RIGHT_PAREN 11
#define SUBSCRIPT 12
#define MODULE 13
#define ERROR 19
/**************************
* Token types
*************************/
/*
* Operators
*/
#define PLUS 20 /* + */
#define MINUS 21 /* - */
#define TIMES 22 /* * */
#define DIVIDE 23 /* / */
#define NOT_EQUAL 24 /* <> */
#define LESS_EQUAL 25 /* <= */
#define GREATER_EQUAL 26 /* >= */
#define LESS 27 /* < */
#define GREATER 28 /* > */
#define EQUAL 29 /* = */
#define EQUATE 30 /* := */
#define COLON 31 /* : */
#define AT_OP 32 /* @ */
/*
* Reserved word values
*/
/* Statements */
#define DECLARE 40
#define DO 41
#define END 42
#define IF 43
#define THEN 44
#define ELSE 45
#define GOTO 46
#define GO 47
#define CALL 48
#define RETURN 49
#define DISABLE 50
#define ENABLE 51
#define OUTPUT 52
#define OUTWORD 53
#define OUTHWORD 54
/* Operators */
#define AND 60
#define OR 61
#define XOR 62
#define NOT 63
#define MOD 64
/* DO options */
#define CASE 70
#define WHILE 71
#define TO 72
#define BY 73
/* DECLARE types */
#define BYTE 80
#define WORD 81
#define DWORD 82
#define INTEGER 83
#define REAL 84
#define ADDRESS 85
#define SELECTOR 86
#define POINTER 87
#define STRUCTURE 88
/* DECLARE options */
#define BASED 90
#define LITERALLY 91
#define DATA 92
#define EXTERNAL 93
#define INITIAL 94
#define PUBLIC 95
#define AT 96
/* Misc reserved words */
#define PROCEDURE 101
#define REENTRANT 102
#define INTERRUPT 103
/* Control Directives */
#define C_CODE 200
#define C_NOCODE 201
#define C_COND 202
#define C_NOCOND 203
#define C_DEBUG 204
#define C_NODEBUG 205
#define C_EJECT 206
#define C_IF 207
#define C_ELSEIF 208
#define C_ELSE 209
#define C_ENDIF 210
#define C_INCLUDE 211
#define C_INTERFACE 212
#define C_LEFTMARGIN 213
#define C_LIST 214
#define C_NOLIST 215
#define C_OBJECT 216
#define C_NOOBJECT 217
#define C_OPTIMIZE 218
#define C_OVERFLOW 219
#define C_NOOVERFLOW 220
#define C_PAGELENGTH 221
#define C_PAGEWIDTH 222
#define C_PAGING 223
#define C_NOPAGING 224
#define C_PRINT 225
#define C_NOPRINT 226
#define C_RAM 227
#define C_ROM 228
#define C_SAVE 229
#define C_RESTORE 230
#define C_SET 231
#define C_RESET 232
#define C_SMALL 233
#define C_COMPACT 234
#define C_MEDIUM 235
#define C_LARGE 236
#define C_SUBTITLE 237
#define C_SYMBOLS 238
#define C_NOSYMBOLS 239
#define C_TITLE 240
#define C_TYPE 241
#define C_NOTYPE 242
#define C_XREF 243
#define C_NOXREF 244
#define C_INTVECTOR 245
#define C_NOINTVECTOR 246
#define C_MOD86 247
#define C_MOD186 248
#define C_WORD16 249
#define C_WORD32 250

View File

@@ -0,0 +1,6 @@
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef short INTEGER;
typedef float REAL;

View File

@@ -0,0 +1 @@
char version[] = "Version 1.02 (Alpha)";