/*
* mgl.h - Definitions for the Menu Generation Language
*
* Copyright (C) 1997-2003 Gero Kuhlmann <gero@gkminix.han.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: mgl.h,v 1.4 2003/01/25 23:29:44 gkminix Exp $
*/
/*
***************************************************************************
*
* Miscellaneous defines
*/
#define YY_NO_UNPUT /* don't let flex include yyunput */
#define MAX_INT 0x7fff /* max value for integer */
#define MAX_CHAR 0xff /* max value for character */
#define MAX_ID_LEN 16 /* max length of symbold name */
#define MAX_STR_LEN 255 /* max length for strings */
#define MAX_ERRS 32 /* max number of compiler errors */
#define MAX_EXPRS 8 /* max number of expressions */
#define MAX_LEVELS 8 /* max number of nesting levels */
#define MAX_ARRAY_SIZE 16384 /* max size of an array in bytes */
#define MAX_REC_SIZE 8096 /* max size of a record in bytes */
/* Define addresses in data segment for predefined variables */
#define ADDR_SERVERNAME 0x0100 /* server name */
#define ADDR_HOSTNAME 0x0200 /* clients host name */
#define PREDEF_SIZE ((MAX_STR_LEN+1) * 2) /* total size of predef vars */
/*
***************************************************************************
*
* Type for addresses. This has to be signed in order to allow for negative
* address offsets. For the same reason we need at least 32 bits even though
* all addresses are always 16 bits.
*/
#if SIZEOF_UNSIGNED_SHORT >= 4
typedef short addr_t;
#else
# if SIZEOF_UNSIGNED_INT >= 4
typedef int addr_t;
# else
typedef long addr_t;
# endif
#endif
/*
***************************************************************************
*
* Command codes in expressions
*/
#define CMD_NONE 0x00 /* no command */
#define CMD_CONST 0x01 /* expression is a constant */
#define CMD_VAR 0x02 /* expression is a variable */
#define CMD_EQ 0x03 /* equal */
#define CMD_GT 0x04 /* greater than */
#define CMD_GE 0x05 /* greater or equal */
#define CMD_LT 0x06 /* lower than */
#define CMD_LE 0x07 /* lower or equal */
#define CMD_NE 0x08 /* not equal */
#define CMD_CMP 0x09 /* comparison - not used by parser */
#define CMD_OR 0x0a
#define CMD_XOR 0x0b
#define CMD_AND 0x0c
#define CMD_NOT 0x0d
#define CMD_ORD 0x0e /* get ordinal number of scalar */
#define CMD_ODD 0x0f /* odd function */
#define CMD_CHR 0x10 /* convert a number into a character */
#define CMD_SUCC 0x11 /* increase scalar to next ordinal no */
#define CMD_PRED 0x12 /* decrease scalar to next ordinal no */
#define CMD_ABS 0x13 /* abs function */
#define CMD_SQR 0x14 /* square function */
#define CMD_FIRSTFUNC 0x60 /* ID of first function */
#define CMD_USERFUNC 0x60 /* user defined function */
#define CMD_MENU 0x61 /* menu */
#define CMD_FIRSTINT 0x62 /* ID of first internal function */
/* Internal functions. These values are also passed to the runtime dispatcher */
#define CMD_CLS 0x62 /* clear screen */
#define CMD_GOTOXY 0x63 /* got a screen position */
#define CMD_GETBOOTP 0x64 /* get string from BOOTP record */
#define CMD_PUTBOOTP 0x65 /* get string from BOOTP record */
#define CMD_STRLEN 0x66 /* determine length of string */
#define CMD_STRSUB 0x67 /* return substring */
/* Check for conditional command */
#define iscmdcond(a) ((a)->opcode >= CMD_EQ && (a)->opcode <= CMD_NE)
/* Check for general scalar commands */
#define iscmdscalar(a) ((a)->opcode == CMD_ORD || (a)->opcode == CMD_PRED || \
(a)->opcode == CMD_SUCC)
/* Check for logical command */
#define iscmdlogical(a) ((a)->opcode >= CMD_OR && (a)->opcode <= CMD_NOT)
/* Check for associative command, e.g. A^(B^C) == (A^B)^C */
#define iscmdassoc(a) ((a)->opcode == '+' || (a)->opcode == '*' || \
(a)->opcode == CMD_OR || (a)->opcode == CMD_XOR || \
(a)->opcode == CMD_AND)
/* Check for commutative command, e.g. A^B == B^A */
#define iscmdcommut(a) ((a)->opcode == '+' || (a)->opcode == '*' || \
(a)->opcode == CMD_EQ || (a)->opcode == CMD_NE || \
(a)->opcode == CMD_OR || (a)->opcode == CMD_XOR || \
(a)->opcode == CMD_AND)
/* Check for function command */
#define iscmdfunc(a) ((a)->opcode >= CMD_FIRSTFUNC)
/* Check for internal function command */
#define iscmdintfunc(a) ((a)->opcode >= CMD_FIRSTINT)
/*
***************************************************************************
*
* Encoding of types.
*/
/* Basic types */
typedef enum {
EXPR_NONE, /* no assigned type */
EXPR_STRING, /* string type */
EXPR_NUM, /* numerical type */
EXPR_BOOL, /* boolean type */
EXPR_CHAR, /* character type */
EXPR_ENUM, /* enumeration type */
EXPR_ARRAY, /* array type */
EXPR_RECORD /* record type */
} basictypes;
/* Definitions for scalar types */
struct scalar_type {
int min; /* Minimum value for scalar type */
int max; /* Maximum value for scalar type */
addr_t boundaddr; /* Addr of bounds in const seg */
};
/* Definitions for array type (also for strings) */
struct array_type {
int elementnum; /* Number of elements in array */
struct typesdef *indextype; /* Type of index */
struct typesdef *basetype; /* Type of each element */
};
/* Definitions for record type */
struct record_type {
int elementnum; /* Number of elements in record */
struct sym *elements; /* Symbols for all elements */
}; /* These symbols are NOT part of */
/* ... the global symbol list!!! */
/* Global structure holding all type information */
struct typesdef {
basictypes type; /* Identifier for type */
addr_t size; /* Total size of type */
union {
struct scalar_type s; /* Definitions for scalar types */
struct array_type a; /* Definitions for an array */
struct record_type r; /* Definitions for a record */
} def;
struct typesdef *next; /* Pointer to next type */
};
/* Predefined type definitions */
extern struct typesdef none_type; /* type not defined */
extern struct typesdef int_type; /* integer type */
extern struct typesdef string_type; /* string type */
extern struct typesdef strindex_type; /* default string index type */
extern struct typesdef char_type; /* character type */
extern struct typesdef bool_type; /* boolean type */
/* Check if a type is scalar */
#define isscalar(a) ((a)->type == EXPR_NUM || (a)->type == EXPR_CHAR || \
(a)->type == EXPR_BOOL || (a)->type == EXPR_ENUM)
/* Check if a type is non-scalar type, only strings as of yet */
#define isnonscalar(a) ((a)->type == EXPR_STRING || \
(a)->type == EXPR_ARRAY || \
(a)->type == EXPR_RECORD)
/*
***************************************************************************
*
* Attributes for variables and function arguments
*/
typedef enum {
ATTR_NONE, /* no special attribute, normal variable */
ATTR_REF, /* variable is an arg passed by reference */
ATTR_CONST /* passed by value but never changed */
} varattrib;
/*
***************************************************************************
*
* Encoding of symbols. The level value is the current nesting level. If
* it's greater than zero, the address is relative to the level's frame
* pointer.
*/
struct vardef {
struct typesdef *t; /* type definition of variable */
varattrib attr; /* attribute of variable */
};
struct constdef {
struct typesdef *t; /* type of constant */
union {
int i; /* constant integer value */
char *s; /* constant string value */
char c; /* constant character value */
int b; /* constant boolean value */
int e; /* constant enumeration value */
} val;
};
struct funcdef {
addr_t restartaddr; /* Restartaddress */
addr_t retaddr; /* BP relative address of return value */
int opcode; /* command value (see below) */
int argnum; /* Number of arguments */
struct typesdef *ret; /* return type of function */
struct typesdef *args[MAX_EXPRS]; /* expression types of args */
varattrib attribs[MAX_EXPRS]; /* argument attributes */
};
/* Special symbols are only used within the lexer, never passed to the parser */
struct specialdef {
int token; /* token to return to parser */
};
/*
***************************************************************************
*
* Symbol table
*/
typedef enum symtype {
nosym,
specialsym,
varsym,
constsym,
typesym,
funcsym
} symtype;
struct sym {
symtype type; /* symbol type */
char *name; /* name of symbol */
addr_t addr; /* address of symbol */
int level; /* nesting level of symbol */
union {
struct funcdef f; /* function declaration */
struct specialdef s; /* special symbol for lexer */
struct vardef v; /* variable declaration */
struct constdef c; /* constant declaration */
struct typesdef *t; /* type declaration */
} def;
struct sym *next; /* pointer to next symbol */
};
/* Check if symbol is not declared yet */
#define isnosym(a) ((a) != NULL && (a)->type == nosym)
/* Check for special lexer symbol */
#define isspecialsym(a) ((a) != NULL && (a)->type == specialsym)
/* Check for variable symbol */
#define isvarsym(a) ((a) != NULL && (a)->type == varsym)
/* Check for constant symbol */
#define isconstsym(a) ((a) != NULL && (a)->type == constsym)
/* Check for function symbol */
#define isfuncsym(a) ((a) != NULL && (a)->type == funcsym)
/* Check for function symbol */
#define istypesym(a) ((a) != NULL && (a)->type == typesym)
/*
*****************************************************************************
*
* In order to create a symbol list like <symbol>,<symbol>,... for enume-
* rations or variable declarations, we use a temporary list, which contains
* the symbol links. Analogous we use a type list.
*/
struct symlist {
int num; /* Current symbol number */
struct sym *sym; /* Pointer to symbol */
struct symlist *next; /* Pointer to next list entry */
};
struct typelist {
struct typesdef *t; /* Pointer to type */
struct typelist *next; /* Pointer to next list entry */
};
/*
***************************************************************************
*
* Definitions to build expression tree
*/
/* Structure to hold variable information in an expression */
struct varinfo {
struct sym *symbol; /* pointer to variable symbol */
struct typesdef *type; /* type of variable */
struct expr *index; /* index in an array */
struct varinfo *next; /* pointer to next record in */
}; /* ... record definition */
/* Structure of one expression node */
struct expr {
struct typesdef *type; /* type of expression */
int opcode; /* type of operation */
int exprnum; /* number of subexpressions */
struct expr *exprlist[MAX_EXPRS]; /* list of subexpressions */
union {
struct constdef cval; /* constant value */
struct varinfo var; /* variable definition */
struct sym *func; /* function pointer */
} spec;
};
#define left exprlist[0] /* left (or only) expr tree */
#define right exprlist[1] /* right expression tree */
/* Get expression type - this is used so often, that it's better in a macro */
#define exprtype(a) ((a)->type == NULL ? EXPR_NONE : (a)->type->type)
/* Check if an expression is constant */
#define isconst(a) ((a)->opcode == CMD_CONST && (a)->exprnum == 0)
/* Check if an expression is a variable */
#define isvariable(a) ((a)->opcode == CMD_VAR && (a)->exprnum == 0)
/* Check if an expression is a leaf node */
#define isleaf(a) ((a)->exprnum == 0 && \
((a)->opcode == CMD_VAR || \
(a)->opcode == CMD_CONST))
/* Check if an expression is a procedure call */
#define isproc(a) ((a)->type == NULL && iscmdfunc(a))
/* Check if an expression is a function call */
#define isfunc(a) ((a)->type != NULL && iscmdfunc(a))
/*
***************************************************************************
*
* Definition of operation codes to be used in the interface from the
* parser to the code generator.
*/
typedef enum {
CODE_PROC_START,
CODE_PROC_END,
CODE_RESTART,
CODE_CALL_PROC,
CODE_ASSIGN,
CODE_INT_PRINT,
CODE_STR_PRINT,
CODE_CHAR_PRINT,
CODE_INT_GET,
CODE_STR_GET,
CODE_CHAR_GET,
CODE_PUSH_IPADDR,
CODE_LOAD,
CODE_IF,
CODE_ELSE,
CODE_WHILE,
CODE_REPEAT,
CODE_SELECT,
CODE_ITEM,
CODE_ENDNEST,
CODE_BREAK
} codes;
/*
***************************************************************************
*
* External functions
*/
extern void interror __P((int num, char *msg));
extern void warning __P((char *msg));
extern void error __P((char *msg));
extern void yyerror __P((char *msg));
extern int yylex __P((void));
extern int yyparse __P((void));
extern void yylexinit __P((char *infile));
extern void yylexterm __P((void));
extern void print_token __P((void));
extern int getord __P((struct expr *ep));
extern void delexpr __P((struct expr *ep));
extern struct expr *reorg __P((struct expr *ep));
extern void docmd __P((codes cmd, struct sym *sp,
struct expr *ep1, struct expr *ep2));
/*
***************************************************************************
*
* External variables
*/
extern char *curfile; /* name of current input file */
extern struct sym *symtab; /* symbol table */
extern struct sym *curproc; /* pointer to current menu */
extern struct typesdef *typetab; /* types table */
extern int lineno; /* current line number */
extern int warnings; /* number of warnings */
extern int errors; /* number of errors */
extern int curlevel; /* current nesting level */
extern char *yytext; /* current token */
syntax highlighted by Code2HTML, v. 0.9.1