%{
  /*
BOIL (Brunni's Own Interpreter Language)
(c) 1998 netEstate (http://www.netestate.de/, info@netestate.de),
Michael Brunnbauer & Markus Hendel, Gesellschaft fuer Netzwerkkommunikation bR
Am Bluetenanger 8, 80995 Muenchen, Germany

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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "general.h"
#include "handles.cc"
#include "boil.h"
#ifdef WITH_RPC
#include "rpc.h"
#endif

int yylex();
void yyerror(char* s);

%}

%union {

string* t0;
int t1; /* type */
type_value* t2; /* const */
type_reference* t3;
type_expr_list* t4;
type_function_call* t5;
type_expr* t6;
type_arg_list* t7;
type_function_dekl* t8;
type_dekl_list_entry* t9;
type_dekl_list* t10;
type_variable_dekl* t11;
type_expr_stmt* t12;
type_choice_stmt* t13;
type_loop_stmt* t14;
type_jump_stmt* t15;
type_stmt* t16;
type_stmt_list* t17;
type_block* t18;
type_arg_list_entry* t19;
type_eval_stmt* t20;
type_external_stmt* t21;
}

/* nonsemantic terminal tokens */

/* keywords */
%token LONG DOUBLE STRING VOID IF ELSE FOR WHILE DO BREAK CONTINUE RETURN
%token UNSIGNED EVAL EXTERNAL

/* operators */
%right '='
%left OR
%left AND
%left '|'
%left '^'
%left '&'
%left EQUAL NOTEQUAL
%left '<' '>' LE GE
%left SHIFTLEFT SHIFTRIGHT
%left '+' '-'
%left '*' '/' '%'
%right PLUSPLUS MINUSMINUS '~' '!' NEG CAST
%left FUNC
%token '(' ')' '[' ']'

/* terminal tokens */

%token <t2> CONST
%token <t0> NAME
%token <t0> PRINT

/* nonterminal tokens */

%type <t18> block
%type <t1> type
%type <t3> reference
%type <t4> expr_list
%type <t5> function_call
%type <t6> expr
%type <t19> arg_list_entry
%type <t7> arg_list
%type <t8> function_dekl
%type <t9> dekl_list_entry
%type <t10> dekl_list
%type <t11> variable_dekl
%type <t12> expr_stmt
%type <t13> choice_stmt
%type <t14> loop_stmt
%type <t15> jump_stmt
%type <t16> stmt
%type <t17> stmt_list
%type <t20> eval_stmt
%type <t21> external_stmt

%%
block:                          '{' '}'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"block: '{' '}'");
#endif
  $$ = new type_block();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  type_stmt_list* stmt_list=new type_stmt_list();
  if (!stmt_list) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->stmt_list=stmt_list;
  type_stack_entry stke;
  $$->stack.insert_listelem(stke);
  $$->file=filei;
  $$->perms=0xFFFFFFFF;
  instoken(TYPE_BLOCK,$$);
}
                        |       '{' stmt_list '}'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"block: '{' stmt_list '}'");
#endif
  $$ = new type_block();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->stmt_list=$2;
  type_stack_entry stke;
  $$->stack.insert_listelem(stke);
  $$->file=filei;
  $$->perms=0xFFFFFFFF;
  instoken(TYPE_BLOCK,$$);
  deltoken($2);
}
;

type:				LONG
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"type: LONG");
#endif
  $$ = TYPE_VALUE_LONG;
}
                        |       UNSIGNED LONG
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"type: UNSIGNED LONG");
#endif
  $$ = TYPE_VALUE_ULONG;
}
			|	DOUBLE
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"type: DOUBLE");
#endif
  $$ = TYPE_VALUE_DOUBLE;
}
			|	STRING
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"type: STRING");
#endif
  $$ = TYPE_VALUE_STRING;
}
                        |       VOID
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"type: VOID");
#endif
  $$ = TYPE_VALUE_VOID;
}
;

reference:                      NAME
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"reference: NAME");
#endif
  $$ = new type_reference();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_REFERENCE_SIMPLE;
  $$->name=*$1;
  $$->file=filei;
  instoken(TYPE_REFERENCE,$$);
  delete $1;
}
                        |       '[' expr ']'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"reference: '[' expr ']'");
#endif
  $$ = new type_reference();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_REFERENCE_COMPLEX;
  $$->counter=0;
  $$->expr=$2;
  $$->file=filei;
  instoken(TYPE_REFERENCE,$$);
  deltoken($2);
}
                        |       '[' expr ',' expr ']'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"reference: '[' expr ',' expr ']'");
#endif
  $$ = new type_reference();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_REFERENCE_COMPLEX;
  $$->counter=$4;
  $$->expr=$2;
  $$->file=filei;
  instoken(TYPE_REFERENCE,$$);
  deltoken($2);
  deltoken($4);
}
;

expr_list:                      expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr_list: expr");
#endif
  $$ = new type_expr_list();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->exprs.insert_listelem(*$1);
  instoken(TYPE_EXPR_LIST,$$);
  delete $1;
  deltoken($1);
}
                        |       expr_list ',' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr_list: expr_list ',' expr");
#endif
  $1->exprs.insert_listelem(*$3,$1->exprs.length());
  $$=$1;
  delete $3;
  deltoken($3);
}
;

function_call:                  reference '(' expr_list ')' %prec FUNC
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_call: reference '(' expr_list ')'");
#endif
  $$ = new type_function_call();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->reference=$1;
  $$->expr_list=$3;
  $$->file=filei;
  $$->nofatal=0;
  instoken(TYPE_FUNCTION_CALL,$$);
  deltoken($1);deltoken($3);
}
                        |       reference '(' ')' %prec FUNC
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"function_call: reference '(' ')'");
#endif
  $$ = new type_function_call();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->reference=$1;
  type_expr_list* expr_list=new type_expr_list();
  if (!expr_list) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->expr_list=expr_list;
  $$->file=filei;
  $$->nofatal=0;
  instoken(TYPE_FUNCTION_CALL,$$);
  deltoken($1);
}
                        |       '(' reference ')' '(' expr_list ')' %prec FUNC
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_call: '(' reference ')' '(' expr_list ')'");
#endif
  $$ = new type_function_call();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->reference=$2;
  $$->expr_list=$5;
  $$->file=filei;
  $$->nofatal=1;
  instoken(TYPE_FUNCTION_CALL,$$);
  deltoken($2);deltoken($5);
}
                        |       '(' reference ')' '(' ')' %prec FUNC
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_call: '(' reference ')' '(' ')'");
#endif
  $$ = new type_function_call();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->reference=$2;
  type_expr_list* expr_list=new type_expr_list();
  if (!expr_list) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->expr_list=expr_list;
  $$->file=filei;
  $$->nofatal=1;
  instoken(TYPE_FUNCTION_CALL,$$);
  deltoken($2);
}
;

expr:                           CONST
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: CONST");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_CONST;
  $$->uptr.constant=$1;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
}
                        |       reference
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: reference");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_REFERENCE;
  $$->uptr.reference=$1;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
}
                        |       function_call
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: function_call");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_FUNCTION_CALL;
  $$->uptr.function_call=$1;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
}
                        |       reference '=' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: reference '=' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_ASSIGNMENT;
  $$->uptr.reference=$1;
  $$->expr1=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       reference PLUSPLUS
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: reference PLUSPLUS");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_POSTINKREMENT;
  $$->uptr.reference=$1;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
}
                        |       reference MINUSMINUS
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: reference MINUSMINUS");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_POSTDEKREMENT;
  $$->uptr.reference=$1;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
}
                        |       PLUSPLUS reference
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: PLUSPLUS reference");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_PREINCREMENT;
  $$->uptr.reference=$2;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($2);
}
                        |       MINUSMINUS reference
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: MINUSMINUS reference");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_PREDECREMENT;
  $$->uptr.reference=$2;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($2);
}
                        |       '(' expr ')'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: '(' expr ')'");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_EXPR;
  $$->expr1=$2;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($2);
}
                        |       '(' type ')' expr %prec CAST
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: '(' type ')' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_CAST;
  $$->expr1=$4;
  $$->cast=$2;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($4);
}
                        |       '-' expr %prec NEG
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: '-' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_ONE;
  $$->optype=TYPE_OPERATOR_ONE_NEG_AR;
  $$->expr1=$2;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($2);
}
                        |       '~' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: '~' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_ONE;
  $$->optype=TYPE_OPERATOR_ONE_NEG_BIT;
  $$->expr1=$2;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($2);
}
                        |       '!' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: '!' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_ONE;
  $$->optype=TYPE_OPERATOR_ONE_NEG_BOOL;
  $$->expr1=$2;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($2);
}
                        |       expr '*' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '*' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_MULT;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '/' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '/' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_DIV;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '%' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '%' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_MODULO;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '+' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '+' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_PLUS;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '-' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '-' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_MINUS;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr SHIFTLEFT expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr SHIFTLEFT expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_SHIFTLEFT;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr SHIFTRIGHT expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr SHIFTRIGHT expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_SHIFTRIGHT;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '<' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '<' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_LOWER;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '>' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '>' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_GREATER;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr LE expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr LE expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_LE;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr GE expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr GE expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_GE;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr EQUAL expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr EQUAL expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_EQUAL;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr NOTEQUAL expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr NOTEQUAL expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_NOTEQUAL;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '&' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '&' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_AND_BIT;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '^' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '^' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_EOR_BIT;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr '|' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr '|' expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_OR_BIT;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr AND expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr AND expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_AND_BOOL;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
                        |       expr OR expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr: expr OR expr");
#endif
  $$ = new type_expr();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_OPERATOR_TWO;
  $$->expr1=$1;
  $$->optype=TYPE_OPERATOR_TWO_OR_BOOL;
  $$->expr2=$3;
  $$->file=filei;
  instoken(TYPE_EXPR,$$);
  deltoken($1);
  deltoken($3);
}
;

arg_list_entry:                 type NAME
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"arg_list_entry: type NAME");
#endif
  $$ = new type_arg_list_entry();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->argtype=$1;
  $$->argname=*$2;
  $$->file=filei;
  instoken(TYPE_ARG_LIST_ENTRY,$$);
  delete $2;
}
;

arg_list:                       arg_list_entry
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"arg_list: arg_list_entry");
#endif
  $$ = new type_arg_list();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->args.insert_listelem(*$1);
  instoken(TYPE_ARG_LIST,$$);
  delete $1;
  deltoken($1);
}
                        |       arg_list ',' arg_list_entry
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"arg_list: arg_list ',' arg_list_entry");
#endif
  $1->args.insert_listelem(*$3,$1->args.length());
  $$=$1;
  delete $3;
  deltoken($3);
}
;

function_dekl:                  type reference external_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: external_stmt");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_EXTERNAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  type_arg_list* arg_list=new type_arg_list();
  if (!arg_list) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->args=arg_list;
  $$->external_stmt=$3;
  $$->opt_expr=0;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($3);
}
                        |       type reference '(' arg_list ')' block
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: type reference '(' arg_list ')' block");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_NORMAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  $$->args=$4;
  $$->myblock=$6;
  $$->opt_expr=0;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($4);
  deltoken($6);
}
			|	type reference '(' ')' block
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: type reference '(' ')' block");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_NORMAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  type_arg_list* arg_list=new type_arg_list();
  if (!arg_list) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->args=arg_list;
  $$->myblock=$5;
  $$->opt_expr=0;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($5);
}
                        |       type reference '(' arg_list ')' eval_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: type reference '(' arg_list ')' eval_stmt");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_EVAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  $$->args=$4;
  $$->eval_stmt=$6;
  $$->opt_expr=0;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($4);
  deltoken($6);
}
                        |       type reference '(' ')' eval_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: type reference '(' ')' eval_stmt");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_EVAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  type_arg_list* arg_list=new type_arg_list();
  if (!arg_list) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->args=arg_list;
  $$->eval_stmt=$5;
  $$->opt_expr=0;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($5);
}
                        |       type reference '(' expr ',' arg_list ')' block
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: type reference '(' expr ',' arg_list ')' block");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_NORMAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  $$->opt_expr=$4;
  $$->args=$6;
  $$->myblock=$8;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($4);
  deltoken($6);
  deltoken($8);
}
                        |       type reference '(' expr ')' block
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: type reference '(' expr ')' block");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_NORMAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  $$->opt_expr=$4;
  type_arg_list* arg_list=new type_arg_list();
  if (!arg_list) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->args=arg_list;
  $$->myblock=$6;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($4);
  deltoken($6);
}
                        |       type reference '(' expr ',' arg_list ')'
                                eval_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: type reference '(' expr ',' arg_list ')' eval_stmt");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_EVAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  $$->opt_expr=$4;
  $$->args=$6;
  $$->eval_stmt=$8;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($4);
  deltoken($6);
  deltoken($8);
}
                        |       type reference '(' expr ')' eval_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "function_dekl: type reference '(' expr ')' eval_stmt");
#endif
  $$ = new type_function_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->type=TYPE_FUNC_DEKL_EVAL;
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->returntype=$1;
  $$->reference=$2;
  $$->opt_expr=$4;
  type_arg_list* arg_list=new type_arg_list();
  if (!arg_list) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->args=arg_list;
  $$->eval_stmt=$6;
  $$->file=filei;
  instoken(TYPE_FUNCTION_DEKL,$$);
  deltoken($2);
  deltoken($4);
  deltoken($6);
}
;

dekl_list_entry:                reference
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"dekl_list_entry: reference");
#endif
  $$ = new type_dekl_list_entry();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_DEKL_LIST_ENTRY_REF;
  $$->reference=$1;
  $$->file=filei;
  instoken(TYPE_DEKL_LIST_ENTRY,$$);
  deltoken($1);
}
                        |       reference '=' expr
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"dekl_list_entry: reference '=' expr");
#endif
  $$ = new type_dekl_list_entry();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_DEKL_LIST_ENTRY_REFINIT;
  $$->reference=$1;
  $$->expr=$3;
  $$->file=filei;
  instoken(TYPE_DEKL_LIST_ENTRY,$$);
  deltoken($1);
  deltoken($3);
}
;

dekl_list:                      dekl_list_entry
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"dekl_list: dekl_list_entry");
#endif
  $$ = new type_dekl_list();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->entrys.insert_listelem(*$1);
  instoken(TYPE_DEKL_LIST,$$);
  delete $1;
  deltoken($1);
}
                        |       dekl_list ',' dekl_list_entry
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "dekl_list: dekl_list ',' dekl_list_entry");
#endif
  $1->entrys.insert_listelem(*$3,$1->entrys.length());
  $$=$1;
  delete $3;
  deltoken($3);
}
;

variable_dekl:                  type dekl_list ';'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"variable_dekl: type dekl_list ';'");
#endif
  $$ = new type_variable_dekl();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->vartype=$1;
  $$->dekl_list=$2;
  $$->file=filei;
  instoken(TYPE_VARIABLE_DEKL,$$);
  deltoken($2);
}
;

expr_stmt:                      ';'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr_stmt: ';'");
#endif
  $$ = new type_expr_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_STMT_EMPTY;
  $$->file=filei;
  instoken(TYPE_EXPR_STMT,$$);
}
                        |       expr ';'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"expr_stmt: expr ';'");
#endif
  $$ = new type_expr_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_EXPR_STMT_DEFINED;
  $$->expr=$1;
  $$->file=filei;
  instoken(TYPE_EXPR_STMT,$$);
  deltoken($1);
}
;

choice_stmt:                    IF '(' expr ')' stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"choice_stmt: IF '(' expr ')' stmt");
#endif
  $$ = new type_choice_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_CHOICE_STMT_IF;
  $$->expr=$3;
  $$->stmt1=$5;
  $$->file=filei;
  instoken(TYPE_CHOICE_STMT,$$);
  deltoken($3);
  deltoken($5);
}
                        |       IF '(' expr ')' stmt ELSE stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "choice_stmt: IF '(' expr ')' stmt ELSE stmt");
#endif
  $$ = new type_choice_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_CHOICE_STMT_ELSE;
  $$->expr=$3;
  $$->stmt1=$5;
  $$->stmt2=$7;
  $$->file=filei;
  instoken(TYPE_CHOICE_STMT,$$);
  deltoken($3);
  deltoken($5);
  deltoken($7);
}
;

loop_stmt:                      WHILE '(' expr ')' stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"loop_stmt: WHILE '(' expr ')' stmt");
#endif
  $$ = new type_loop_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_LOOP_STMT_WHILE;
  $$->expr=$3;
  $$->stmt=$5;
  $$->expr_for=0;
  $$->stmt_for=0;
  $$->file=filei;
  instoken(TYPE_LOOP_STMT,$$);
  deltoken($3);
  deltoken($5);
}
                        |       DO stmt WHILE '(' expr ')' ';'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "loop_stmt: DO stmt WHILE '(' expr ')' ';'");
#endif
  $$ = new type_loop_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_LOOP_STMT_DO;
  $$->expr=$5;
  $$->stmt=$2;
  $$->expr_for=0;
  $$->stmt_for=0;
  $$->file=filei;
  instoken(TYPE_LOOP_STMT,$$);
  deltoken($2);
  deltoken($5);
}
                        |       FOR '(' stmt expr ';' expr ')' stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "loop_stmt: FOR '(' stmt expr ';' expr ')' stmt");
#endif
  $$ = new type_loop_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_LOOP_STMT_FOR;
  $$->expr=$4;
  $$->expr_for=$6;
  $$->stmt=$8;
  $$->stmt_for=$3;
  $$->file=filei;
  instoken(TYPE_LOOP_STMT,$$);
  deltoken($3);
  deltoken($4);
  deltoken($6);
  deltoken($8);
}
                        |       FOR '(' stmt ';' expr ')' stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "loop_stmt: FOR '(' stmt ';' expr ')' stmt");
#endif
  $$ = new type_loop_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_LOOP_STMT_FOR;
  $$->expr=0;
  $$->expr_for=$5;
  $$->stmt=$7;
  $$->stmt_for=$3;
  $$->file=filei;
  instoken(TYPE_LOOP_STMT,$$);
  deltoken($3);
  deltoken($5);
  deltoken($7);
}
                        |       FOR '(' stmt expr ';' ')' stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "loop_stmt: FOR '(' stmt expr ';' ')' stmt");
#endif
  $$ = new type_loop_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_LOOP_STMT_FOR;
  $$->expr=$4;
  $$->expr_for=0;
  $$->stmt=$7;
  $$->stmt_for=$3;
  $$->file=filei;
  instoken(TYPE_LOOP_STMT,$$);
  deltoken($3);
  deltoken($4);
  deltoken($7);
}
                        |       FOR '(' stmt ';' ')' stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"loop_stmt: FOR '(' stmt ';' ')' stmt");
#endif
  $$ = new type_loop_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_LOOP_STMT_FOR;
  $$->expr=0;
  $$->expr_for=0;
  $$->stmt=$6;
  $$->stmt_for=$3;
  $$->file=filei;
  instoken(TYPE_LOOP_STMT,$$);
  deltoken($3);
  deltoken($6);
}
;

jump_stmt:                      BREAK ';'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"jump_stmt: BREAK ';'");
#endif
  $$ = new type_jump_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_JUMP_STMT_BREAK;
  $$->file=filei;
  instoken(TYPE_JUMP_STMT,$$);
}
                        |       CONTINUE ';'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"jump_stmt: CONTINUE ';'");
#endif
  $$ = new type_jump_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_JUMP_STMT_CONTINUE;
  $$->file=filei;
  instoken(TYPE_JUMP_STMT,$$);
}
                        |       RETURN ';'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"jump_stmt: RETURN ';'");
#endif
  $$ = new type_jump_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_JUMP_STMT_RETURN;
  $$->file=filei;
  instoken(TYPE_JUMP_STMT,$$);
}
                        |       RETURN expr ';'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"jump_stmt: RETURN expr ';'");
#endif
  $$ = new type_jump_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_JUMP_STMT_RETURNVAL;
  $$->expr=$2;
  $$->file=filei;
  instoken(TYPE_JUMP_STMT,$$);
  deltoken($2);
}
;

eval_stmt:                      EVAL '(' expr ')'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "stmt: eval '(' expr ')'");
#endif
  $$ = new type_eval_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->expr_code=$3;
  $$->file=filei;
  instoken(TYPE_EVAL_STMT,$$);
  deltoken($3);
}
;

external_stmt:                  EXTERNAL '(' expr ',' expr ',' expr ')'
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,
      "stmt: external '(' expr ',' expr ',' expr ',' expr ')'");
#endif
  $$ = new type_external_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->expr_handle=$3;
  $$->expr_function=$5;
  $$->expr_pw=$7;
  $$->file=filei;
  instoken(TYPE_EXTERNAL_STMT,$$);
  deltoken($3);
  deltoken($5);
  deltoken($7);
}
;

stmt:                           variable_dekl
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt: variable_dekl");
#endif
  $$ = new type_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_STMT_VARIABLE_DEKL;
  $$->uptr.variable_dekl=$1;
  $$->file=filei;
  instoken(TYPE_STMT,$$);
  deltoken($1);
}
                        |       function_dekl
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt: function_dekl");
#endif
  $$ = new type_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_STMT_FUNCTION_DEKL;
  $$->uptr.function_dekl=$1;
  $$->file=filei;
  instoken(TYPE_STMT,$$);
  deltoken($1);
}
                        |       expr_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt: expr_stmt");
#endif
  $$ = new type_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_STMT_EXPR_STMT;
  $$->uptr.expr_stmt=$1;
  $$->file=filei;
  instoken(TYPE_STMT,$$);
  deltoken($1);
}
                        |       block
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt: block");
#endif
  $$ = new type_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_STMT_BLOCK;
  $$->uptr.block=$1;
  $$->file=filei;
  instoken(TYPE_STMT,$$);
  deltoken($1);
}
                        |       choice_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt: choice_stmt");
#endif
  $$ = new type_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_STMT_CHOICE_STMT;
  $$->uptr.choice_stmt=$1;
  $$->file=filei;
  instoken(TYPE_STMT,$$);
  deltoken($1);
}
                        |       loop_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt: loop_stmt");
#endif
  $$ = new type_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_STMT_LOOP_STMT;
  $$->uptr.loop_stmt=$1;
  $$->file=filei;
  instoken(TYPE_STMT,$$);
  deltoken($1);
}
                        |       jump_stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt: jump_stmt");
#endif
  $$ = new type_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_STMT_JUMP_STMT;
  $$->uptr.jump_stmt=$1;
  $$->file=filei;
  instoken(TYPE_STMT,$$);
  deltoken($1);
}
                        |       PRINT
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt: PRINT");
#endif
  $$ = new type_stmt();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
#ifdef YYLSP_NEEDED
  $$->line=@1.first_line;
#endif
  $$->type=TYPE_STMT_PRINT_STMT;
  $$->print_stmt=*$1;
  $$->file=filei;
  instoken(TYPE_STMT,$$);
  delete $1;
}
;

stmt_list:                      stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt_list: stmt");
#endif
  $$ = new type_stmt_list();
  if (!$$) { log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL); };
  $$->stmts.insert_listelem(*$1);
  instoken(TYPE_STMT_LIST,$$);
  delete $1;
  deltoken($1);
}
                        |       stmt_list stmt
{
#ifdef DEBUGGING
  log(LOG_DEBUG,__FILE__,__LINE__,0,"stmt_list: stmt_list stmt");
#endif
  $1->stmts.insert_listelem(*$2,$1->stmts.length());
  $$=$1;
  delete $2;
  deltoken($2);
}
;

%%

/*

nonsemantic terminal tokens
---------------------------

LONG long
DOUBLE double
STRING string
VOID void
IF if
ELSE else
WHILE while
DO do
BREAK break
CONTINUE continue
RETURN return

SHIFTLEFT <<
SHIFTRIGHT >>
LE <=
GE >=
EQUAL ==
NOTEQUAL !=
AND &&
OR ||
PLUSPLUS ++
MINUSMINUS --

{ } * , ( ) - ! ~ / % + < > & ^ | = ; [ ]

terminal tokens
---------------

CONST
NAME

*/

joined_list<FILE*> prgs;
joined_list<char*> prgstrs;

joined_list<unsigned int> lines;
joined_list<string> files;
joined_list<unsigned int> fileis;

joined_list<string> filenames;

string directive,directive_arg;

int yylex()
{
  int c;
  char buf[2];
  buf[1]=0;
  type_value val;
  unsigned long number;

while (1)
  {
    if (first)
      {
	first=0;

	if (!first_line)
	  {
	    while (pgetchar()!='\n') { ; };
	  };

	if (embed)
	  {
	    wtype=T_PRINT;
#ifdef YYLSP_NEEDED
	    yylloc.first_line=line;
#endif
	    return '{';
	  };
      };

    if (lastchar)
      {
	c=lastchar;
	lastchar=0;
      }
    else
      {
	c=pgetchar();
      };

#ifdef YYLSP_NEEDED
    if (wtype==T_UNDEF)
      {
	yylloc.first_line=line;
      };
#endif
    
    /* EOF */
    if (!c || c==EOF || last)
      {
	if (prgs.length())
	  {
	    fclose(prg);
	    prg=prgs[0];
	    line=lines[0];
	    file=files[0];
            filei=fileis[0];
	    prgstr=prgstrs[0];
	    prgs.remove_listelem(0);
            lines.remove_listelem(0);
	    files.remove_listelem(0);
            fileis.remove_listelem(0);
	    prgstrs.remove_listelem(0);
	    return yylex();
	  };

	if (embed && !last)
	  {
	    last=1;
	    if (wtype==T_PRINT)
	      {
		wtype=T_UNDEF;
		string* ptr=new string();
		if (!ptr)
                    {
                      log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,0);
                    };
		*ptr=w;
		yylval.t0=ptr;
		return PRINT;
	      }
	    else
	      {
		/* syntax error */
#ifdef DEBUGGING
		log(LOG_DEBUG,__FILE__,__LINE__,0,
		    "file ends with code");
#endif
		return 0;
	      };
	  }
	else if (embed && wtype==T_UNDEF)
	  {
	    wtype=T_EOF;
	    return '}';
	  }
	else if (!embed || wtype==T_EOF)
	  {
	    return 0;
	  };
      };

    switch (wtype)
      {
      case T_WORD:
	{
	  /* complete ? */
	  if (c<48 || 
	      (c>57 && c<65) ||
	      (c>90 && c<97 && c!='_') ||
	      c>122)
	    {
	      lastchar=c;
	      wtype=T_UNDEF;
	      
	      if (w=="long") { return LONG; }
	      else if (w=="double") { return DOUBLE; }
	      else if (w=="string") { return STRING; }
	      else if (w=="void") { return VOID; }
	      else if (w=="if") { return IF; }
	      else if (w=="else") { return ELSE; }
	      else if (w=="for") { return FOR; }
	      else if (w=="while") { return WHILE; }
	      else if (w=="do") { return DO; }
	      else if (w=="break") { return BREAK; }
	      else if (w=="continue") { return CONTINUE; }
	      else if (w=="unsigned") { return UNSIGNED; }
	      else if (w=="eval") { return EVAL; }
	      else if (w=="external") { return EXTERNAL; }
	      else if (w=="return") { return RETURN; };

	      string* ptr=new string();
	      if (!ptr)
		{
		  log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,0);
		};
	      *ptr=w;
	      yylval.t0=ptr;
	      return NAME;
	    }
	  else
	    {
	      buf[0]=c;
	      w+=buf;
	    };
	  continue;
	};
      case T_CONST_DEZ:
	{
	  /* switch to double ? */
	  if (c=='e' || c=='E' || c=='.')
	    {
	      buf[0]=c;
	      w+=buf;
	      wtype=T_CONST_DOUBLE;
	    }
	  else if (c<48 || c>57) /* complete ? */
	    {
	      lastchar=c;
	      wtype=T_UNDEF;
	      
	      if (sscanf(w,"%lf",&val.val.doubleval)==1)
		{
		  if (((unsigned long) val.val.doubleval)!=val.val.doubleval)
		    {
		      /* parse error */
#ifdef DEBUGGING
		      log(LOG_DEBUG,__FILE__,__LINE__,0,
			  "%s is too big",(char*) w);
#endif
		      return 0;
		    };

		  if (((long) val.val.doubleval) < 0)
		    {
		      val.type=TYPE_VALUE_ULONG;
		      val.val.ulongval=(unsigned long) val.val.doubleval;
		    }
		  else
		    {
                      val.type=TYPE_VALUE_LONG;
                      val.val.longval=(long) val.val.doubleval;
		    };

		  type_value* ptr=new type_value();
		  if (!ptr)
		    {
		      log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL);
		    };
		  *ptr=val;
		  yylval.t2=ptr;
		  return CONST;
		}
	      else
		{
                  /* parse error */
#ifdef DEBUGGING
                  log(LOG_DEBUG,__FILE__,__LINE__,0,
                      "%s is not an integer",(char*) w);
#endif
                  return 0;
		};
	    }
	  else
	    {
              buf[0]=c;
              w+=buf;
	    };
	  continue;
	};
      case T_CONST_DOUBLE:
	{
	  /* complete ? */
	  if ((c<48 && c!='.' && c!='-') ||
	      (c>57 && c!='e' && c!='E'))
	    {
              lastchar=c;
              wtype=T_UNDEF;
	      
	      if (sscanf(w,"%lf",&val.val.doubleval)==1)
		{
		  val.type=TYPE_VALUE_DOUBLE;
		  type_value* ptr=new type_value();
		  if (!ptr)
		    {
		      log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL);
		    };
		  *ptr=val;
		  yylval.t2=ptr;
		  return CONST;
		}
	      else
		{
		  /* parse error */
#ifdef DEBUGGING
		  log(LOG_DEBUG,__FILE__,__LINE__,0,
		      "%s is not a double",(char*) w);
#endif
		  return 0;
		};
	    }
	  else
	    {
	      buf[0]=c;
	      w+=buf;
	    };
	  continue;
	};
      case T_CONST_HEX:
	{
          /* complete ? */
          if (c<48 || (c>57 && c<65) || (c>70 && c<97) || c>102)
            {
              lastchar=c;
              wtype=T_UNDEF;
              if (sscanf(w,"%lx",&val.val.longval)==1)
		{
		  val.type=TYPE_VALUE_LONG;
                  type_value* ptr=new type_value();
                  if (!ptr)
                    {
                      log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL);
                    };
                  *ptr=val;
                  yylval.t2=ptr;
                  return CONST;
		}
	      else
                {
		  /* parse error */
#ifdef DEBUGGING
                  log(LOG_DEBUG,__FILE__,__LINE__,0,
                      "%s is not a hex long",(char*) w);
#endif
                  return 0;
                };
            }
          else
	    {
              buf[0]=c;
              w+=buf;
	    };
	  continue;
	};
      case T_CONST_OCT:
	{
          /* complete ? */
          if (c<48 || c>55)
	    {
              lastchar=c;
              wtype=T_UNDEF;
              if (sscanf(w,"%lo",&val.val.longval)==1)
                {
                  val.type=TYPE_VALUE_LONG;
                  type_value* ptr=new type_value();
                  if (!ptr)
                    {
                      log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL);
                    };
                  *ptr=val;
                  yylval.t2=ptr;
                  return CONST;
                }
              else
                {
                  /* parse error */
#ifdef DEBUGGING
                  log(LOG_DEBUG,__FILE__,__LINE__,0,
                      "%s is not an octal long",(char*) w);
#endif
                  return 0;
                };
            }
          else
            {
              buf[0]=c;
              w+=buf;
            };
	  continue;
	};
      case T_CONST_STRING:
	{
	  if (c=='\\')
	    {
	      c=pgetchar();
	      if (!c || c==EOF)
		{
#ifdef DEBUGGING
		  log(LOG_DEBUG,__FILE__,__LINE__,0,
		      "unexpected EOF");
#endif
		  return 0;
		};
	      switch (c)
		{
		case 'n': { w+="\n"; break; };
		case 't': { w+="\t"; break; };
		case 'v': { w+="\v"; break; };
		case 'b': { w+="\b"; break; };
		case 'r': { w+="\r"; break; };
		case 'f': { w+="\f"; break; };
		case 'a': { w+="\a"; break; };
		case '\\': { w+="\\"; break; };
		case '\?': { w+="\?"; break; };
		case '\'': { w+="\'"; break; };
		case '\"': { w+="\""; break; };
		case '\n': { break; };
		case 'x' :
		  {
		    /* hex char */
		    w1="";
		    wtype=T_CONST_STRING_HEX;
		    break;
		  };
		default:
		  {
		    /* octal char ? */
		    if (c>48 && c<56)
		      {
			buf[0]=c;
			w1=buf;
			wtype=T_CONST_STRING_OCT;
			break;
		      };
		    
#ifdef DEBUGGING
		    log(LOG_DEBUG,__FILE__,__LINE__,0,
			"illegal character after \\: %c",(char) c);
#endif
		    return 0;
		  };
		};
	    }
	  else if (c=='\"')
	    {
	      wtype=T_UNDEF;
	      val.type=TYPE_VALUE_STRING;
	      val.stringval=w;
	      type_value* ptr=new type_value();
	      if (!ptr)
		{
		  log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,0);
		};
	      *ptr=val;
	      yylval.t2=ptr;
	      return CONST;
	    }
	  else
	    {
	      buf[0]=c;
	      w+=buf;
	    };
	  continue;
	};
      case T_CONST_STRING_HEX:
	{
	  /* complete ? */
	  if (c<48 || (c>57 && c<65) || (c>70 && c<97) || c>102)
	    {
	      lastchar=c;
	      if (sscanf(w1,"%lx",&number)!=1)
		{
#ifdef DEBUGGING
		  log(LOG_DEBUG,__FILE__,__LINE__,0,
		      "not a valid hex-number: %s",(char*) w1);
#endif
		  
		return 0;
		};
	      buf[0]=(number&0xff);
	      w+=buf;
	      wtype=T_CONST_STRING;
	    }
	  else
	    {
              buf[0]=c;
              w1+=buf;
            };
          continue;
	};
      case T_CONST_STRING_OCT:
	{
          /* complete ? */
          if (c<48 || c>55)
            {
              lastchar=c;
              if (sscanf(w1,"%lo",&number)!=1)
                {
#ifdef DEBUGGING
                  log(LOG_DEBUG,__FILE__,__LINE__,0,
                      "not a valid octal number: %s",(char*) w1);
#endif
                return 0;
                };
              buf[0]=(number&0xff);
              w+=buf;
              wtype=T_CONST_STRING;
            }
          else
            {
              buf[0]=c;
              w1+=buf;
            };
	  continue;
	};
      case T_COMMENT_LINE:
	{
	  /* complete ? */
	  if (c=='\n') { wtype=T_UNDEF; };
	  continue;
	};
      case T_COMMENT:
	{
	  if (c=='*')
	    {
	      c=pgetchar();
	      if (!c || c==EOF)
		{
#ifdef DEBUGGING
		  log(LOG_DEBUG,__FILE__,__LINE__,0,
		      "unexpected EOF");
#endif
		  return 0;
		};
	      if (c=='/') { wtype=T_UNDEF; };
	    };
	  continue;
	};
      case T_PRINT:
	{
	  if (c=='<')
	    {
              c=pgetchar();
              if (!c || c==EOF)
                {
#ifdef DEBUGGING
                  log(LOG_DEBUG,__FILE__,__LINE__,0,
                      "unexpected EOF");
#endif
                  return 0;
                };
              if (c=='?')
		{
		  wtype=T_UNDEF;
		  string* ptr=new string();
		  if (!ptr)
		    {
		      log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,0);
		    };
		  *ptr=w;
		  yylval.t0=ptr;
		  return PRINT;
		}
	      else
		{
		  buf[0]=c;
		  w+="<";
		  w+=buf;
		};
            }
	  else
	    {
	      buf[0]=c;
	      w+=buf;
	    };
          continue;
	};
      case T_DIRECTIVE:
	{
	  if (c==' ')
	    {
	      wtype=T_DIRECTIVE_ARG;
	      directive=w;
	      w="";
	    }
	  else
	    {
              buf[0]=c;
              w+=buf;
	    };
	  continue;
	};
      case T_DIRECTIVE_ARG:
	{
	  if (c=='\n')
	    {
	      wtype=T_UNDEF;
	      directive_arg=w;

	      if (directive=="include")
		{
		  if (prgs.length()>=max_parse_recursions)
		    {
#ifdef DEBUGGING
		      log(LOG_DEBUG,__FILE__,__LINE__,0,
                          "include-statement: maximum number of parser-\
recursions reached");
#endif
                      return 0;
		    };
		  prgs.insert_listelem(prg);
		  lines.insert_listelem(line);
                  files.insert_listelem(file);
                  fileis.insert_listelem(filei);
                  prgstrs.insert_listelem(prgstr);
		  line=1;
                  file=directive_arg;
                  filenames.insert_listelem(file,filenames.length());
                  filei=filenames.length()-1;
		  prg=fopen(directive_arg,"r");
		  if (!prg)
		    {
#ifdef DEBUGGING
		      log(LOG_DEBUG,__FILE__,__LINE__,0,
			  "include-statement: cannot fopen() %s",
			  (char*) directive_arg);
#endif
		      perror("reason: ");
		      return 0;
		    };
		  
		  return yylex();
		}
	      else
		{
#ifdef DEBUGGING
		  log(LOG_DEBUG,__FILE__,__LINE__,0,
		      "unknown directive");
#endif
		  return 0;
		};
	    }
	  else
	    {
              buf[0]=c;
              w+=buf;
	    };
	  continue;
	};

      };
    
    /* so we have something new, a unique char ? */
    if (c=='{' || 
	c=='}' ||
	c=='[' ||
	c==']' ||
	c=='*' || 
	c==',' || 
	c=='(' || 
	c==')' ||
	c=='~' ||
	c=='%' ||
	c=='^' ||
	c==';')
      {
	return c;
      };

    /* a special char ? */
    if (c=='\"')
      {
	wtype=T_CONST_STRING;
	w="";
	continue;
      };
    if (c==' ' || c=='\n' || c==13)
      {
	continue;
      };
    if (c=='\\')
      {
#ifdef DEBUGGING
	log(LOG_DEBUG,__FILE__,__LINE__,0,
	    "\\ only allowed in string-constants");
#endif
	return 0;
      };
    if (c=='#')
      {
	wtype=T_DIRECTIVE;
	w="";
	directive="";
	directive_arg="";
	continue;
      };

    /* a dezimal number ? */
    if (c>48 && c<58)
      {
	buf[0]=c;
        w=buf;
        wtype=T_CONST_DEZ;
	continue;
      };

    /* a double ? */
    if (c=='.')
      {
        buf[0]=c;
        w=buf;
        wtype=T_CONST_DOUBLE;
        continue;
      };

    /* a number in 0... notation ? */
    if (c=='0')
      {
	c=pgetchar();
	if (!c || c==EOF)
	  {
#ifdef DEBUGGING
	    log(LOG_DEBUG,__FILE__,__LINE__,0,
		"unexpected EOF");
#endif
	    return 0;
	  };
	if (c=='x')
	  {
	    w="";
	    wtype=T_CONST_HEX;
	  }
	else if (c>=48 && c<=55)
	  {
	    buf[0]=c;
	    w=buf;
	    wtype=T_CONST_OCT;
	  }
	else if (c=='.')
	  {
	    buf[0]=c;
            w=buf;
	    wtype=T_CONST_DOUBLE;
	  }
	else
	  {
	    /* it's simply a zero */
	    lastchar=c;
	    val.val.longval=0;
	    val.type=TYPE_VALUE_LONG;
	    type_value* ptr=new type_value();
	    if (!ptr)
	      {
		log(LOG_FATAL,__FILE__,__LINE__,ERROR_OUT_OF_MEM,NULL);
	      };
	    *ptr=val;
	    yylval.t2=ptr;
	    return CONST;
	  };
	continue;
      };

    /* or a name ? */
    if ((c>=65 && c<=90) || (c>=97 && c<=122) || c=='_')
      {
	buf[0]=c;
        w=buf;
	wtype=T_WORD;
	continue;
      };
	
    /* HA ! now it must be one of < > = ! & | + - / ? */
    buf[0]=c;
    lastchar=c=pgetchar();
    if (!c || c==EOF)
      {
#ifdef DEBUGGING
	log(LOG_DEBUG,__FILE__,__LINE__,0,
	    "unexpected EOF");
#endif
	return 0;
      };

    switch (buf[0])
      {
      case '-':
	{
	  if (c=='-')
	    {
	      lastchar=0;
	      return MINUSMINUS;
	    };
	  return buf[0];
	};
      case '!':
	{
          if (c=='=')
	    {
	      lastchar=0;
	      return NOTEQUAL;
	    };
          return buf[0];
	};
      case '+':
	{
          if (c=='+')
	    {
	      lastchar=0;
	      return PLUSPLUS;
	    };
          return buf[0];
	};
      case '<':
	{
          if (c=='<')
	    {
	      lastchar=0;
	      return SHIFTLEFT;
	    };
          if (c=='=')
	    {
	      lastchar=0;
	      return LE;
	    };
          return buf[0];
	};
      case '>':
	{
          if (c=='>')
	    {
	      lastchar=0;
	      return SHIFTRIGHT;
	    };
          if (c=='=')
	    {
	      lastchar=0;
	      return GE;
	    };
          return buf[0];
	};
      case '&':
	{
          if (c=='&')
	    {
	      lastchar=0;
	      return AND;
	    };
          return buf[0];
	};
      case '|':
	{
          if (c=='|')
	    {
	      lastchar=0;
	      return OR;
	    };
          return buf[0];
	};
      case '=':
	{
          if (c=='=')
	    {
	      lastchar=0;
	      return EQUAL;
	    };
          return buf[0];
	};
      case '/':
	{
	  if (c=='/')
	    {
	      wtype=T_COMMENT_LINE;
	    }
	  else if (c=='*')
	    {
	      wtype=T_COMMENT;
	    }
	  else
	    {
	      return buf[0];
	    };
	  continue;
	};
      case '?':
	{
	  if (c=='>')
	    {
	      w="";
	      lastchar=0;
	      wtype=T_PRINT;
	    }
	  else
	    {
#ifdef DEBUGGING
	      log(LOG_DEBUG,__FILE__,__LINE__,0,
		  "illegal character");
#endif
	      return 0;
	    };
	  continue;
	};
      default:
	{
#ifdef DEBUGGING
	  log(LOG_DEBUG,__FILE__,__LINE__,0,
	      "illegal character");
#endif
	  return 0;
	};
      };
  };

};

void yyerror(char* s)
{
  s=s;
  return;
}
