
#define NUM_FUNC              100
#define NUM_GLOBAL_VARS       100
#define NUM_LOCAL_VARS        200
#define NUM_BLOCK             100
#define ID_LEN                31
#define FUNC_CALLS            31
#define NUM_PARAMS            31
#define LOOP_NEST             31
#define FUNC_MAX_ARGS         16

#define DELIMITER             1
#define IDENTIFIER            2
#define NUMBER                3
#define KEYWORD               4
#define TEMP                  5
#define STRING                6
#define BLOCK                 7

#define TOKEN_CHAR            1
#define TOKEN_INT             2
#define TOKEN_IF              3
#define TOKEN_ELSE            4
#define TOKEN_FOR             5
#define TOKEN_DO              6
#define TOKEN_WHILE           7
#define TOKEN_RETURN          8
#define TOKEN_SWITCH          9
#define TOKEN_CASE            10
#define TOKEN_BREAK           11
#define TOKEN_CONTINUE        12
#define TOKEN_EOL             13
#define TOKEN_FINISHED        14
#define TOKEN_END             15

#define _RETURN               0
#define _GO_ON                1
#define _BREAK                2
#define _CONTINUE             3

#define E_SYNTAX              1
#define E_UNBAL_PARENS,       2
#define E_NO_EXP              3
#define E_EQUALS_EXPECTED     4
#define E_NOT_VAR             5
#define E_PARAM_ERR           6
#define E_SEMI_EXPECTED       7
#define E_UNBAL_BRACES        8
#define E_FUNC_UNDEF          9
#define E_TYPESPEC_EXPECTED   10
#define E_NEST_FUNC           11
#define E_RET_NOCALL          12
#define E_PAREN_EXPECTED      13
#define E_WHILE_EXPECTED      14
#define E_QUOTE_EXPECTED      15
#define E_NOT_TEMP            16
#define E_TOO_MANY_LVARS      17
#define E_NO_MAIN             18

#define LT                    1
#define LE                    2
#define GT                    3
#define GE                    4
#define EQ                    5
#define NE                    6
#define OR                    7
#define AND                   8



typedef struct variable {
  char name[ID_LEN];
  char type;
  char ispointer;
  union {
    char c;
    int i;
    double f;
    int all[2];                         // allows copying of the value as
                                        // 2*32 bits regardless of the type
  } value;
} variable;

typedef struct internal_function {
  char *f_name;                         // function name
  void (* p)(struct variable *retval);  // pointer to the function
  char minargc, maxargc;
  char argtypes[FUNC_MAX_ARGS];
} internal_function;

typedef struct function {
  char func_name[ID_LEN];
  char *loc;                            // location of entry point in file
  char argc;
  char argtypes[FUNC_MAX_ARGS];
} function;

typedef struct commands {               // keyword lookup table
  char command[20];
  char tok;
} commands;



extern char *prog;                      // points to current location in program
extern char token[1024];                // holds string representation of token
extern char token_type;                 // contains type of token
extern char tok;                        // holds the internal representation of token
extern char *p_buf;                     // points to start of program buffer
extern jmp_buf e_buf;                   // hold environment for longjmp()

extern struct variable global_vars[NUM_GLOBAL_VARS];

extern struct variable local_var_stack[NUM_LOCAL_VARS];

extern struct function func_table[NUM_FUNC];

extern int call_stack[NUM_FUNC];

extern struct commands table[];

extern int functos;                     // index to top of function call stack
extern int func_index;                  // index into function table
extern int gvar_index;                  // index into global variable table
extern int lvartos;                     // index into local variable stack

extern struct variable ret_value;       // function return value

int microc_start(char *ptr, int(* unknown_function)(char *), int(* poll)(char *));

void prescan(void);
void decl_global(void);
void decl_local(void);
void local_push(struct variable *i);
void get_params(void);
void get_args(void);
void func_push(int i);
int func_pop(void);
void func_ret(void);
void sntx_err(int error);
int exec_if(void);
int exec_for(void);
int exec_while(void);
int exec_do(void);
void find_eob(void);
struct variable *find_var(char *s);
int interp_block(void);

void print(struct variable *value);
void call_getche(struct variable *value);
void call_putch(struct variable *value);
void call_puts(struct variable *value);
void getnum(struct variable *value);

void eval_exp(struct variable *value);
void eval_exp1(struct variable *value);
void eval_exp2(struct variable *value);
void eval_exp3(struct variable *value);
void eval_exp4(struct variable *value);
void eval_exp5(struct variable *value);
void atom(struct variable *value);
void eval_exp0(struct variable *value);
void sntx_err(int error);
void putback(void);
void assign_var(char *name, struct variable *value);
int isdelim(char c);
int look_up(char *s);
int iswhite(char c);
int get_token(void);
int internal_func(char *s);
int is_var(char *s);
struct function *find_func(char *name);
void call(struct function *func);
