/* * mgl.h - Definitions for the Menu Generation Language * * Copyright (C) 1997-2003 Gero Kuhlmann * * 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 ,,... 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 */