%token <ldata> NUMBER
%token <ldata> VARIABLE
%token <ldata> FUNCTION
%token EOL

%pure_parser

%left '<' '>' '='
%left '+' '-'
%left '*' '/'
%left NEG
%right '^'

%{
#define __grammar_h

#include <PalmOS.h>
#include "parse.h"

  /* Allocate memory from the dynamic heap and not the stack... */
#define __builtin_alloca(x) MemPtrNew(x)
#define free(x)             MemPtrFree(x)
#define CPlex               Lexer

#define YYPARSE_PARAM data
#define YYLEX_PARAM data

  /*
   * Bison's initial stack is allocated on the /Palms/ initial
   * stack. Eeek! 200 entries is enough to fill it almost to
   * bursting. It does indeed burst and spew its guts everywhere when
   * MathLib comes into the equation. So, we redefine this to
   * something titchy
   */
#define YYINITDEPTH 5
%}

%union {
  LexerData          ldata;
  struct ParseTree*  ptree;
}

%type <ptree> expression
%type <ptree> subexpression

%token <ldata> '+' '-' '*' '/' '^'

%{
extern int Lexer(YYSTYPE* data, ParserData* pdata);
%}

%{
#define PData ((ParserData*) data)

#define NextStore \
  PData->storePos++; \
  if (PData->storePos >= PData->storeSize) \
    { \
      MemHandleUnlock(PData->storeHandle); \
      PData->storeSize += 32; \
      if (MemHandleResize(PData->storeHandle, \
                          sizeof(ParseTree)*PData->storeSize)) \
        { \
	  yyerror("Memory full"); \
	  YYERROR; \
	} \
      PData->store = MemHandleLock(PData->storeHandle); \
    }

#define Store PData->store[PData->storePos]
#define LastPos &PData->store[PData->storePos-1]
%}

%start line

%%

line:		  expression
		    {
		      ((ParserData *)data)->result = $1;
		    }
		;

expression:	  expression '+' expression 
		    {
		      Store.nodeData = $2;
		      Store.left     = $1;
		      Store.right    = $3;
		      NextStore;
		      $$ = LastPos;
		    }
		| expression '-' expression
		    {
		      Store.nodeData = $2;
		      Store.left     = $1;
		      Store.right    = $3;
		      NextStore;
		      $$ = LastPos;
		    }
		| expression '/' expression {}
		    {
		      Store.nodeData = $2;
		      Store.left     = $1;
		      Store.right    = $3;
		      NextStore;
		      $$ = LastPos;
		    }
		| expression '*' expression {}
		    {
		      Store.nodeData = $2;
		      Store.left     = $1;
		      Store.right    = $3;
		      NextStore;
		      $$ = LastPos;
		    }
		| expression '^' expression {}
		    {
		      Store.nodeData = $2;
		      Store.left     = $1;
		      Store.right    = $3;
		      NextStore;
		      $$ = LastPos;
		    }
		| subexpression
		    {
		      $$ = $1;
		    }
		| '-' subexpression %prec NEG
		    {
		      Store.nodeData.type = Number;
		      Store.nodeData.data.number = 0.0;
		      Store.left = Store.right = NULL;
		      NextStore;

		      Store.nodeData = $1;
		      Store.left     = LastPos;
		      Store.right    = $2;
		      NextStore;
		      $$ = LastPos;
		    }
		;

subexpression:	  NUMBER
		    {
		      Store.nodeData = $1;
		      Store.left     = Store.right = NULL;
		      NextStore;
		      $$ = LastPos;
		    }
		| '(' expression ')'
		    {
		      $$ = $2;
		    }
		;

%%
