/*(( "Kopf" */
/* -----------------------------------------------------------------------------

   $Id: semantics.h,v 1.2 1997/06/13 05:34:03 mshopf Exp mshopf $

   GoldED API client, ©1997 Matthias Hopf.
   Compiled with SasC.


   Parser functions and list of available semantics.

   ------------------------------------------------------------------------------
*/

/*)) */
#ifndef _SEMANTICS_H
#define _SEMANTICS_H

/*(( "Includes" */

#include "smartindent.h"
#include "util.h"

#include <proto/exec.h>

#include <stdio.h>
#include <ctype.h>
#include <string.h>

/*)) */

/*(( "Macros" */

/* endless loop detection debug macros */

#ifdef DEBUG
extern int Dbug_Counter;
#define DEBUG_COUNTER (Dbug ? 5000 : 100000)
#  define dcheck        do { if (Dbug_Counter++ >= DEBUG_COUNTER)                                       \
			     { Printf ("Broke endless loop in %s:%ld", __FILE__, __LINE__);             \
			       ErrRet (c, "!!! Internal - broke endless loop in line %d !!!\n");  }     \
			   } while (0)
#else
#  define dcheck        ((void)0)
#endif

/* Check whether we are at the begin of line */
#define BOL            (c->LastPos < 0)
/* Check whether we are at the end of line */
#define EOL            (c->NextPosEOL < 0)
/* Get Peek buffer */
#define P              (c->PeekBuffer)
/* Get Word buffer */
#define W              (c->WordBuffer)

/* Get current indentation level */
#define I              (c->Indent)
/* Get current column */
#define C              (c->CurrentPos)
/* Get next word column */
#define N              (EOL ? c->CurrentPos + strlen (W) + CONFIG.NextLine_Level : c->NextPos)
/* Get last word column */
#define L              (c->LastPos)
/* Get current configuration */
#define CONFIG         (c->Conf)

/* Just define that we are now at the begin of line */
#define SETBOL         do { c->LastPos = -1; } while (0)
/* Just define that we are now at the end of line */
#define SETEOL         do { c->NextPosEOL = -1; } while (0)
/* define EOL mode as it is in reality */
#define UNSETEOL       do { c->NextPosEOL = c->NextPos; } while (0)
/* Format and set error */
#define ERROR(e)       ErrRet (c, e)
/* Peek next word */
#define PEEK           NextWord (c, P, FALSE)
/* Get next word */
#define GET            do { NextWord (c, W, TRUE); if (! W[0]) return; } while (0)
/* Unget the last word - structure is not completely consistent afterwards, but a rough guess! */
#define UNGET          LastWord (c)
/* Loop: get next word until finished */
#define DOGET          while (NextWord (c, W, TRUE), W[0] && ! c->ErrTxt && c->CurrentLine <= c->EndIndent)

/* Function definition for a semantics Function */
#define FUNC(n)        static void n (sc_t *c, int IndentStack)

/* The calling functions keep Indent unmodified when they
 * return because they reached the last line to be intended. */
/* Push current intendation to stack and call function */
#define CALL1(f)      do { IndentStack = I; f (c, 0); debug (D_RETURN, ("<-%s\t", # f)); if (c->ErrTxt || c->CurrentLine > c->EndIndent) return; I = IndentStack; } while (0)
/* Push current intendation to stack, set new level and call function */
#define CALL(f,i)      do { IndentStack = I; I = i; f (c, 0); debug (D_RETURN, ("<-%s\t", # f)); if (c->ErrTxt || c->CurrentLine > c->EndIndent) return; I = IndentStack; } while (0)

/* Set indentation level and indent */
#define SET(i)         do { I = (i); Move (c, C, (i)); } while (0)
/* Try to indent without changing the level */
#define INDENT(i)      Move (c, C, (i))
/* Try to indent current line and set level to real position */
#define UPDATE(i)      do { Move (c, C, (i)); I = C; } while (0)

/* Try to indent without changing the level only if first word on line */
#define INDFIRST(i)    do { if (BOL) INDENT (i); } while (0)
/* Try to indent current line only if first word on line (e.g. start of command) and set level to real position */
#define UPFIRST(i)     do { if (BOL) UPDATE (i); } while (0)


/*)) */

/*(( "Prototypes and List" */

extern struct Semantic C_Sem;
extern struct Semantic Lisp_Sem;

#define SEMANTICS { &C_Sem, &Lisp_Sem, NULL }
#define SEMANTICS_NAMES "C, Lisp"

/*)) */

#endif /* _SEMANTICS_H_ */

