215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | /*\
||| This file a part of Pike, and is copyright by Fredrik Hubinette
||| Pike is distributed as GPL (General Public License)
||| See the files COPYING and DISCLAIMER for more information.
\*/
%pure_parser
/*
* These values are used by the stack machine, and can not be directly
* called from Pike.
*/
%token F_ADD_256 F_ADD_512 F_ADD_768 F_ADD_1024 F_ADD_256X
%token F_PREFIX_256 F_PREFIX_512 F_PREFIX_768 F_PREFIX_1024
%token F_PREFIX_CHARX256 F_PREFIX_WORDX256 F_PREFIX_24BITX256
%token F_POP_VALUE F_POP_N_ELEMS F_MARK F_MARK2
%token F_CALL_LFUN F_CALL_LFUN_AND_POP
%token F_BRANCH F_BRANCH_WHEN_ZERO F_BRANCH_WHEN_NON_ZERO
%token F_BRANCH_WHEN_LT F_BRANCH_WHEN_GT
%token F_BRANCH_WHEN_LE F_BRANCH_WHEN_GE
%token F_BRANCH_WHEN_EQ F_BRANCH_WHEN_NE
%token F_INC_LOOP F_DEC_LOOP
%token F_INC_NEQ_LOOP F_DEC_NEQ_LOOP
%token F_INDEX F_INDIRECT F_STRING_INDEX F_LOCAL_INDEX
%token F_POS_INT_INDEX F_NEG_INT_INDEX
%token F_LTOSVAL F_LTOSVAL2
%token F_PUSH_ARRAY
%token F_RANGE F_COPY_VALUE
/*
* Basic value pushing
*/
%token F_LFUN F_GLOBAL F_LOCAL
%token F_GLOBAL_LVALUE F_LOCAL_LVALUE
%token F_CLEAR_LOCAL
%token F_CONSTANT F_FLOAT F_STRING
%token F_NUMBER F_NEG_NUMBER F_CONST_1 F_CONST0 F_CONST1 F_BIGNUM
/*
* These are the predefined functions that can be accessed from Pike.
*/
%token F_INC F_DEC F_POST_INC F_POST_DEC F_INC_AND_POP F_DEC_AND_POP
%token F_INC_LOCAL F_INC_LOCAL_AND_POP F_POST_INC_LOCAL
%token F_DEC_LOCAL F_DEC_LOCAL_AND_POP F_POST_DEC_LOCAL
%token F_RETURN F_DUMB_RETURN F_RETURN_0 F_THROW_ZERO
%token F_ASSIGN F_ASSIGN_AND_POP
%token F_ASSIGN_LOCAL F_ASSIGN_LOCAL_AND_POP
%token F_ASSIGN_GLOBAL F_ASSIGN_GLOBAL_AND_POP
%token F_ADD F_SUBTRACT
%token F_MULTIPLY F_DIVIDE F_MOD
%token F_LT F_GT F_EQ F_GE F_LE F_NE
%token F_NEGATE F_NOT F_COMPL
%token F_AND F_OR F_XOR
%token F_LSH F_RSH
%token F_LAND F_LOR
%token F_SWITCH F_SSCANF F_CATCH
%token F_CAST
%token F_FOREACH
%token F_SIZEOF F_SIZEOF_LOCAL
/*
* These are token values that needn't have an associated code for the
* compiled file
*/
%token F_MAX_OPCODE
%token F_ADD_EQ
%token F_AND_EQ
%token F_APPLY
%token F_ARG_LIST
%token F_ARRAY_ID
%token F_ARROW
%token F_BREAK
%token F_CASE
%token F_CLASS
%token F_COLON_COLON
%token F_COMMA
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | %token F_CONSTANT
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | %token F_CONTINUE
%token F_DEFAULT
%token F_DIV_EQ
%token F_DO
%token F_DOT_DOT
%token F_DOT_DOT_DOT
%token F_PREDEF
%token F_EFUN_CALL
%token F_ELSE
%token F_FLOAT_ID
%token F_FOR
%token F_FUNCTION_ID
%token F_GAUGE
%token F_IDENTIFIER
%token F_IF
%token F_INHERIT
%token F_INLINE
%token F_INT_ID
%token F_LAMBDA
%token F_MULTISET_ID
%token F_MULTISET_END
%token F_MULTISET_START
%token F_LOCAL
%token F_LSH_EQ
%token F_LVALUE_LIST
%token F_MAPPING_ID
%token F_MIXED_ID
%token F_MOD_EQ
%token F_MULT_EQ
%token F_NO_MASK
%token F_OBJECT_ID
%token F_OR_EQ
%token F_PRIVATE
%token F_PROGRAM_ID
%token F_PROTECTED
%token F_PUBLIC
%token F_RSH_EQ
%token F_STATIC
%token F_STATUS
%token F_STRING_ID
%token F_SUBSCRIPT
%token F_SUB_EQ
%token F_TYPEOF
%token F_VAL_LVAL
%token F_VARARGS
%token F_VOID_ID
%token F_WHILE
%token F_XOR_EQ
%token F_ALIGN
%token F_POINTER
%token F_LABEL
%token F_MAX_INSTR
%right '='
%right '?'
%left F_LOR
%left F_LAND
%left '|'
%left '^'
%left '&'
%left F_EQ F_NE
%left '>' F_GE '<' F_LE /* nonassoc? */
%left F_LSH F_RSH
%left '+' '-'
|
413c8e | 1996-11-01 | Fredrik Hübinette (Hubbe) | | %left '*' '%' '/'
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | %right F_NOT '~'
%nonassoc F_INC F_DEC
%{
/* This is the grammar definition of Pike. */
#include "global.h"
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include "interpret.h"
#include "array.h"
#include "object.h"
#include "stralloc.h"
#include "las.h"
#include "interpret.h"
#include "lex.h"
#include "program.h"
#include "pike_types.h"
#include "constants.h"
#include "macros.h"
#include "error.h"
#include "docode.h"
#define YYMAXDEPTH 600
static void push_locals();
static void pop_locals();
void free_all_local_names();
void add_local_name(struct pike_string *,struct pike_string *);
/*
* The names and types of arguments and auto variables.
*/
struct locals *local_variables;
static int varargs;
static INT32 current_modifiers;
void fix_comp_stack(int sp)
{
if(comp_stackp>sp)
{
yyerror("Compiler stack fixed.");
comp_stackp=sp;
}else if(comp_stackp<sp){
fatal("Compiler stack frame underflow.");
}
}
%}
%union
{
int number;
FLOAT_TYPE fnum;
unsigned int address; /* Address of an instruction */
struct pike_string *string;
char *str;
unsigned short type;
struct node_s *n;
struct efun *efun;
}
%type <fnum> F_FLOAT
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | %type <string> F_IDENTIFIER
%type <string> F_STRING
%type <string> cast simple_type
%type <string> low_string
%type <string> optional_identifier
%type <string> optional_rename_inherit
%type <string> string_constant
%type <number> F_ARRAY_ID
%type <number> F_BREAK
%type <number> F_CASE
%type <number> F_CATCH
%type <number> F_CONTINUE
%type <number> F_DEFAULT
%type <number> F_DO
%type <number> F_ELSE
%type <number> F_FLOAT_ID
%type <number> F_FOR
%type <number> F_FOREACH
%type <number> F_FUNCTION_ID
%type <number> F_GAUGE
%type <number> F_IF
%type <number> F_INHERIT
%type <number> F_INLINE
%type <number> F_INT_ID
%type <number> F_LAMBDA
%type <number> F_LOCAL
%type <number> F_MAPPING_ID
%type <number> F_MIXED_ID
%type <number> F_MULTISET_ID
%type <number> F_NO_MASK
%type <number> F_NUMBER
%type <number> F_OBJECT_ID
%type <number> F_PREDEF
%type <number> F_PRIVATE
%type <number> F_PROGRAM_ID
%type <number> F_PROTECTED
%type <number> F_PUBLIC
%type <number> F_RETURN
%type <number> F_SSCANF
%type <number> F_STATIC
%type <number> F_STRING_ID
%type <number> F_SWITCH
%type <number> F_VARARGS
%type <number> F_VOID_ID
%type <number> F_WHILE
%type <number> arguments
%type <number> arguments2
%type <number> assign
%type <number> modifier
%type <number> modifier_list
%type <number> modifiers
%type <number> optional_dot_dot_dot
%type <number> optional_stars
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
/* The following symbos return type information */
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | %type <n> assoc_pair
%type <n> block
%type <n> block_or_semi
%type <n> break
%type <n> case
%type <n> catch
%type <n> catch_arg
%type <n> class
%type <n> comma_expr
%type <n> comma_expr2
%type <n> comma_expr_or_maxint
%type <n> comma_expr_or_zero
%type <n> cond
%type <n> continue
%type <n> default
%type <n> do
%type <n> expr00
%type <n> expr01
%type <n> expr1
%type <n> expr2
%type <n> expr3 expr0
%type <n> expr4
%type <n> expr_list
%type <n> expr_list2
%type <n> for
%type <n> for_expr
%type <n> foreach
%type <n> gauge
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | %type <n> idents
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | %type <n> lambda
%type <n> local_name_list
|
3ddb53 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | %type <n> lvalue
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | %type <n> lvalue_list
%type <n> m_expr_list
%type <n> m_expr_list2
%type <n> new_local_name
%type <n> optional_else_part
%type <n> return
%type <n> sscanf
%type <n> statement
%type <n> statements
%type <n> string
%type <n> switch
%type <n> typeof
%type <n> unused
%type <n> unused2
%type <n> while
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | %%
all: program;
program: program def optional_semi_colon
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | /* empty */
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
optional_semi_colon: /* empty */
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | ';' { yyerror("Extra ';'. Ignored."); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
string_constant: low_string
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | string_constant '+' low_string
{
$$=add_shared_strings($1,$3);
free_string($1);
free_string($3);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
optional_rename_inherit: ':' F_IDENTIFIER { $$=$2; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | { $$=0; }
;
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | |
program_ref: string_constant
{
reference_shared_string($1);
push_string($1);
push_string($1);
reference_shared_string(current_file);
push_string(current_file);
SAFE_APPLY_MASTER("handle_inherit", 2);
if(sp[-1].type != T_PROGRAM)
my_yyerror("Couldn't cast program to string (%s)",$1->str);
}
| idents
{
push_string(make_shared_string(""));
switch($1->token)
{
case F_CONSTANT:
if($1->u.sval.type == T_PROGRAM)
{
push_svalue(& $1->u.sval);
}else{
yyerror("Illegal program identifier");
push_int(0);
}
break;
case F_IDENTIFIER:
{
struct identifier *i;
setup_fake_program();
i=ID_FROM_INT(& fake_program, $1->u.number);
if(IDENTIFIER_IS_CONSTANT(i->flags))
{
push_svalue(PROG_FROM_INT(&fake_program, $1->u.number)->constants +
i->func.offset);
}else{
yyerror("Illegal program identifier");
push_int(0);
}
break;
}
}
free_node($1);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | inheritance: modifiers F_INHERIT program_ref optional_rename_inherit ';'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
if(sp[-1].type == T_PROGRAM)
{
s=sp[-2].u.string;
if($4) s=$4;
do_inherit(sp[-1].u.program,$1,s);
if($4) free_string($4);
}
pop_n_elems(2);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | constant_name: F_IDENTIFIER '=' expr0
{
int tmp;
/* This can be made more lenient in the future */
if(!is_const($3))
{
struct svalue tmp;
yyerror("Constant definition is not constant.");
tmp.type=T_INT;
tmp.u.integer=0;
add_constant($1,&tmp, current_modifiers);
} else {
tmp=eval_low($3);
if(tmp < 1)
yyerror("Error in constant definition.");
pop_n_elems(tmp-1);
add_constant($1,sp-1,current_modifiers);
free_string($1);
pop_stack();
}
}
;
constant_list: constant_name
| constant_list ',' constant_name
;
constant: F_CONSTANT modifiers constant_list ';'
;
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | block_or_semi: block
{
$$ = mknode(F_ARG_LIST,$1,mknode(F_RETURN,mkintnode(0),0));
}
| ';' { $$ = NULL;}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
type_or_error: simple_type
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
if(local_variables->current_type)
free_string(local_variables->current_type);
local_variables->current_type=$1;
}
| /* empty */
{
yyerror("Missing type.");
copy_shared_string(local_variables->current_type,
mixed_type_string);
}
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
def: modifiers type_or_error optional_stars F_IDENTIFIER '(' arguments ')'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
int e;
/* construct the function type */
push_finished_type(local_variables->current_type);
while($3--) push_type(T_ARRAY);
if(local_variables->current_return_type)
free_string(local_variables->current_return_type);
local_variables->current_return_type=pop_type();
push_finished_type(local_variables->current_return_type);
e=$6-1;
if(varargs)
{
push_finished_type(local_variables->variable[e].type);
e--;
varargs=0;
pop_type_stack();
}else{
push_type(T_VOID);
}
push_type(T_MANY);
for(; e>=0; e--)
{
push_finished_type(local_variables->variable[e].type);
if($1 & ID_VARARGS)
{
push_type(T_VOID);
push_type(T_OR);
}
}
push_type(T_FUNCTION);
$<string>$=pop_type();
define_function($4,
$<string>$,
$1,
IDENTIFIER_PIKE_FUNCTION,
0);
}
block_or_semi
{
int e;
if($9)
{
union idptr tmp;
int args, vargs;
for(e=0; e<$6; e++)
{
if(!local_variables->variable[e].name ||
!local_variables->variable[e].name->len)
{
my_yyerror("Missing name for argument %d",e);
}
}
tmp.offset=PC;
args=count_arguments($<string>8);
if(args < 0)
{
args=~args;
vargs=IDENTIFIER_VARARGS;
}else{
vargs=0;
}
ins_byte(local_variables->max_number_of_locals, A_PROGRAM);
ins_byte(args, A_PROGRAM);
dooptcode($4, $9, $6);
define_function($4,
$<string>8,
$1,
IDENTIFIER_PIKE_FUNCTION | vargs,
&tmp);
}
if(local_variables->current_return_type)
{
free_string(local_variables->current_return_type);
local_variables->current_return_type=0;
}
free_all_local_names();
free_string($4);
free_string($<string>8);
}
| modifiers type_or_error name_list ';' {}
| inheritance {}
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | | constant {}
| class {}
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | error
{
reset_type_stack();
if(num_parse_error>5) YYACCEPT;
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
optional_dot_dot_dot: F_DOT_DOT_DOT { $$=1; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | /* empty */ { $$=0; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
optional_identifier: F_IDENTIFIER
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | | /* empty */ { $$=0; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | ;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
new_arg_name: type optional_dot_dot_dot optional_identifier
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
if(varargs) yyerror("Can't define more arguments after ...");
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | if($2)
{
push_type(T_ARRAY);
varargs=1;
}
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | if(!$3) $3=make_shared_string("");
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | if(islocal($3) >= 0)
my_yyerror("Variable '%s' appear twice in argument list.",
$3->str);
add_local_name($3, pop_type());
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
arguments: /* empty */ optional_comma { $$=0; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | arguments2 optional_comma { $$=$1; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
arguments2: new_arg_name { $$ = 1; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | arguments2 ',' new_arg_name { $$ = $1 + 1; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
modifier: F_NO_MASK { $$ = ID_NOMASK; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | F_STATIC { $$ = ID_STATIC; }
| F_PRIVATE { $$ = ID_PRIVATE; }
| F_PUBLIC { $$ = ID_PUBLIC; }
| F_VARARGS { $$ = ID_VARARGS; }
| F_PROTECTED { $$ = ID_PROTECTED; }
| F_INLINE { $$ = ID_INLINE | ID_NOMASK; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | modifiers: modifier_list { $$=current_modifiers=$1; } ;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
modifier_list: /* empty */ { $$ = 0; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | modifier modifier_list { $$ = $1 | $2; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
optional_stars: optional_stars '*' { $$=$1 + 1; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | /* empty */ { $$=0; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
cast: '(' type ')' { $$=pop_type(); } ;
type: type '*' { push_type(T_ARRAY); }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | type2
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
simple_type: type2 { $$=pop_type(); }
type2: type2 '|' type3 { push_type(T_OR); }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | type3
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
type3: F_INT_ID { push_type(T_INT); }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | F_FLOAT_ID { push_type(T_FLOAT); }
| F_STRING_ID { push_type(T_STRING); }
| F_PROGRAM_ID { push_type(T_PROGRAM); }
| F_VOID_ID { push_type(T_VOID); }
| F_MIXED_ID { push_type(T_MIXED); }
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | | F_OBJECT_ID opt_object_type { push_type(T_OBJECT); }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | F_MAPPING_ID opt_mapping_type { push_type(T_MAPPING); }
| F_ARRAY_ID opt_array_type { push_type(T_ARRAY); }
| F_MULTISET_ID opt_array_type { push_type(T_MULTISET); }
| F_FUNCTION_ID opt_function_type { push_type(T_FUNCTION); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | opt_object_type: /* Empty */ { push_type_int(0); }
| '(' program_ref ')'
{
if(sp[-1].type == T_PROGRAM)
push_type_int(sp[-1].u.program->id);
pop_n_elems(2);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | opt_function_type: '('
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
type_stack_mark();
type_stack_mark();
}
function_type_list optional_dot_dot_dot ':'
{
if ($4)
{
push_type(T_MANY);
type_stack_reverse();
}else{
type_stack_reverse();
push_type(T_MANY);
push_type(T_VOID);
}
type_stack_mark();
}
type ')'
{
type_stack_reverse();
type_stack_reverse();
}
| /* empty */
{
push_type(T_MIXED);
push_type(T_MIXED);
push_type(T_MANY);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
function_type_list: /* Empty */ optional_comma
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | function_type_list2 optional_comma
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
function_type_list2: type
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | function_type_list2 ','
{
type_stack_reverse();
type_stack_mark();
}
type
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
opt_array_type: '(' type ')'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | { push_type(T_MIXED); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
opt_mapping_type: '('
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
type_stack_mark();
type_stack_mark();
}
type ':'
{
type_stack_reverse();
type_stack_mark();
}
type
{
type_stack_reverse();
type_stack_reverse();
}
')'
| /* empty */
{
push_type(T_MIXED);
push_type(T_MIXED);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
name_list: new_name
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | name_list ',' new_name
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
new_name: optional_stars F_IDENTIFIER
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *type;
push_finished_type(local_variables->current_type);
while($1--) push_type(T_ARRAY);
type=pop_type();
define_variable($2, type, current_modifiers);
free_string(type);
free_string($2);
}
| optional_stars F_IDENTIFIER '='
{
struct pike_string *type;
push_finished_type(local_variables->current_type);
while($1--) push_type(T_ARRAY);
type=pop_type();
$<number>$=define_variable($2, type, current_modifiers);
free_string(type);
}
expr0
{
init_node=mknode(F_ARG_LIST,init_node,
mkcastnode(void_type_string,
mknode(F_ASSIGN,$5,
mkidentifiernode($<number>4))));
free_string($2);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
new_local_name: optional_stars F_IDENTIFIER
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
push_finished_type(local_variables->current_type);
while($1--) push_type(T_ARRAY);
add_local_name($2, pop_type());
$$=mknode(F_ASSIGN,mkintnode(0), mklocalnode(islocal($2)));
}
| optional_stars F_IDENTIFIER '=' expr0
{
push_finished_type(local_variables->current_type);
while($1--) push_type(T_ARRAY);
add_local_name($2, pop_type());
$$=mknode(F_ASSIGN,$4,mklocalnode(islocal($2)));
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
block:'{'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
$<number>$=local_variables->current_number_of_locals;
}
statements '}'
{
while(local_variables->current_number_of_locals > $<number>2)
{
int e;
e=--(local_variables->current_number_of_locals);
free_string(local_variables->variable[e].name);
free_string(local_variables->variable[e].type);
}
$$=$3;
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
local_name_list: new_local_name
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | local_name_list ',' new_local_name { $$=mknode(F_ARG_LIST,$1,$3); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
statements: { $$=0; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | statements statement
{
$$=mknode(F_ARG_LIST,$1,mkcastnode(void_type_string,$2));
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
statement: unused2 ';' { $$=$1; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | cond
| while
| do
| for
| switch
| case
| default
| return ';'
| block {}
| foreach
| break ';'
| continue ';'
| error ';' { $$=0; }
| ';' { $$=0; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
break: F_BREAK { $$=mknode(F_BREAK,0,0); } ;
default: F_DEFAULT ':' { $$=mknode(F_DEFAULT,0,0); } ;
continue: F_CONTINUE { $$=mknode(F_CONTINUE,0,0); } ;
lambda: F_LAMBDA
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
push_locals();
$<number>$=comp_stackp;
if(local_variables->current_return_type)
free_string(local_variables->current_return_type);
copy_shared_string(local_variables->current_return_type,any_type_string);
}
'(' arguments ')' block
{
struct pike_string *type;
char buf[40];
int f,e,args,vargs;
union idptr func;
struct pike_string *name;
setup_fake_program();
fix_comp_stack($<number>2);
push_type(T_MIXED);
e=$4-1;
if(varargs)
{
push_finished_type(local_variables->variable[e].type);
e--;
varargs=0;
pop_type_stack();
}else{
push_type(T_VOID);
}
push_type(T_MANY);
for(; e>=0; e--)
push_finished_type(local_variables->variable[e].type);
push_type(T_FUNCTION);
type=pop_type();
func.offset=PC;
args=count_arguments(type);
if(args < 0)
{
args=~args;
vargs=IDENTIFIER_VARARGS;
}else{
vargs=0;
}
ins_byte(local_variables->max_number_of_locals, A_PROGRAM);
ins_byte(args, A_PROGRAM);
sprintf(buf,"__lambda_%ld",
(long)fake_program.num_identifier_references);
name=make_shared_string(buf);
dooptcode(name,mknode(F_ARG_LIST,$6,mknode(F_RETURN,mkintnode(0),0)),$4);
f=define_function(name,
type,
0,
IDENTIFIER_PIKE_FUNCTION | vargs,
&func);
free_string(name);
free_string(type);
pop_locals();
$$=mkidentifiernode(f);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | class: F_CLASS optional_identifier '{'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
start_new_program();
}
program '}'
{
struct svalue s;
s.u.program=end_program();
if(!s.u.program)
{
yyerror("Class definition failed.");
s.type=T_INT;
s.subtype=0;
} else {
s.type=T_PROGRAM;
s.subtype=0;
}
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | if($2) add_constant($2, &s, 0);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | $$=mksvaluenode(&s);
free_svalue(&s);
}
;
cond: F_IF '(' comma_expr ')' statement optional_else_part
{
$$=mknode('?',$3,mknode(':',$5,$6));
$$->line_number=$1;
$$=mkcastnode(void_type_string,$$);
$$->line_number=$1;
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
optional_else_part: { $$=0; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | F_ELSE statement { $$=$2; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | foreach: F_FOREACH '(' expr0 ',' expr4 ')' statement
{
$$=mknode(F_FOREACH,mknode(F_VAL_LVAL,$3,$5),$7);
$$->line_number=$1;
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
do: F_DO statement F_WHILE '(' comma_expr ')' ';'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
$$=mknode(F_DO,$2,$5);
$$->line_number=$1;
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | for: F_FOR '(' unused ';' for_expr ';' unused ')' statement
{
int i=current_line;
current_line=$1;
$$=mknode(F_ARG_LIST,mkcastnode(void_type_string,$3),mknode(F_FOR,$5,mknode(':',$9,$7)));
current_line=i;
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | while: F_WHILE '(' comma_expr ')' statement
{
int i=current_line;
current_line=$1;
$$=mknode(F_FOR,$3,mknode(':',$5,NULL));
current_line=i;
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
for_expr: /* EMPTY */ { $$=mkintnode(1); }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | comma_expr
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | switch: F_SWITCH '(' comma_expr ')' statement
{
$$=mknode(F_SWITCH,$3,$5);
$$->line_number=$1;
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
case: F_CASE comma_expr ':'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
$$=mknode(F_CASE,$2,0);
}
| F_CASE comma_expr F_DOT_DOT comma_expr ':'
{
$$=mknode(F_CASE,$2,$4);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
return: F_RETURN
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
if(!match_types(local_variables->current_return_type,
void_type_string))
{
yyerror("Must return a value for a non-void function.");
}
$$=mknode(F_RETURN,mkintnode(0),0);
}
| F_RETURN comma_expr
{
$$=mknode(F_RETURN,$2,0);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
unused: { $$=0; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | unused2
;
unused2: comma_expr { $$=mkcastnode(void_type_string,$1); } ;
comma_expr: comma_expr2
| type2
{
if(local_variables->current_type)
free_string(local_variables->current_type);
local_variables->current_type=pop_type();
} local_name_list { $$=$3; }
;
comma_expr2: expr0
| comma_expr2 ',' expr0
{
$$ = mknode(F_ARG_LIST,mkcastnode(void_type_string,$1),$3);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
expr00: expr0
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | '@' expr0 { $$=mknode(F_PUSH_ARRAY,$2,0); };
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
expr0: expr01
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | expr4 '=' expr0 { $$=mknode(F_ASSIGN,$3,$1); }
| expr4 assign expr0 { $$=mknode($2,$1,$3); }
| error assign expr01 { $$=0; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
expr01: expr1 { $$ = $1; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | expr1 '?' expr01 ':' expr01 { $$=mknode('?',$1,mknode(':',$3,$5)); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
assign: F_AND_EQ { $$=F_AND_EQ; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | F_OR_EQ { $$=F_OR_EQ; }
| F_XOR_EQ { $$=F_XOR_EQ; }
| F_LSH_EQ { $$=F_LSH_EQ; }
| F_RSH_EQ { $$=F_RSH_EQ; }
| F_ADD_EQ { $$=F_ADD_EQ; }
| F_SUB_EQ { $$=F_SUB_EQ; }
| F_MULT_EQ{ $$=F_MULT_EQ; }
| F_MOD_EQ { $$=F_MOD_EQ; }
| F_DIV_EQ { $$=F_DIV_EQ; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
optional_comma: | ',' ;
expr_list: { $$=0; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | expr_list2 optional_comma { $$=$1; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
expr_list2: expr00
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | expr_list2 ',' expr00 { $$=mknode(F_ARG_LIST,$1,$3); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
m_expr_list: { $$=0; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | m_expr_list2 optional_comma { $$=$1; }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
m_expr_list2: assoc_pair
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | m_expr_list2 ',' assoc_pair { $$=mknode(F_ARG_LIST,$1,$3); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | assoc_pair: expr0 ':' expr1 { $$=mknode(F_ARG_LIST,$1,$3); } ;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
expr1: expr2
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | expr1 F_LOR expr1 { $$=mknode(F_LOR,$1,$3); }
| expr1 F_LAND expr1 { $$=mknode(F_LAND,$1,$3); }
| expr1 '|' expr1 { $$=mkopernode("`|",$1,$3); }
| expr1 '^' expr1 { $$=mkopernode("`^",$1,$3); }
| expr1 '&' expr1 { $$=mkopernode("`&",$1,$3); }
| expr1 F_EQ expr1 { $$=mkopernode("`==",$1,$3); }
| expr1 F_NE expr1 { $$=mkopernode("`!=",$1,$3); }
| expr1 '>' expr1 { $$=mkopernode("`>",$1,$3); }
| expr1 F_GE expr1 { $$=mkopernode("`>=",$1,$3); }
| expr1 '<' expr1 { $$=mkopernode("`<",$1,$3); }
| expr1 F_LE expr1 { $$=mkopernode("`<=",$1,$3); }
| expr1 F_LSH expr1 { $$=mkopernode("`<<",$1,$3); }
| expr1 F_RSH expr1 { $$=mkopernode("`>>",$1,$3); }
| expr1 '+' expr1 { $$=mkopernode("`+",$1,$3); }
| expr1 '-' expr1 { $$=mkopernode("`-",$1,$3); }
| expr1 '*' expr1 { $$=mkopernode("`*",$1,$3); }
| expr1 '%' expr1 { $$=mkopernode("`%",$1,$3); }
| expr1 '/' expr1 { $$=mkopernode("`/",$1,$3); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
expr2: expr3
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | cast expr2
{
$$=mkcastnode($1,$2);
free_string($1);
}
| F_INC expr4 { $$=mknode(F_INC,$2,0); }
| F_DEC expr4 { $$=mknode(F_DEC,$2,0); }
| F_NOT expr2 { $$=mkopernode("`!",$2,0); }
| '~' expr2 { $$=mkopernode("`~",$2,0); }
| '-' expr2 { $$=mkopernode("`-",$2,0); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
expr3: expr4
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | expr4 F_INC { $$=mknode(F_POST_INC,$1,0); }
| expr4 F_DEC { $$=mknode(F_POST_DEC,$1,0); }
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
expr4: string
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | F_NUMBER { $$=mkintnode($1); }
| F_FLOAT { $$=mkfloatnode($1); }
| catch
| gauge
| typeof
| sscanf
| lambda
| class
|
d2c608 | 1996-11-07 | Fredrik Hübinette (Hubbe) | | | idents
| expr4 '(' expr_list ')' { $$=mkapplynode($1,$3); }
| expr4 '[' expr0 ']' { $$=mknode(F_INDEX,$1,$3); }
| expr4 '[' comma_expr_or_zero F_DOT_DOT comma_expr_or_maxint ']'
{
$$=mknode(F_RANGE,$1,mknode(F_ARG_LIST,$3,$5));
}
| '(' comma_expr2 ')' { $$=$2; }
| '(' '{' expr_list '}' ')'
{ $$=mkefuncallnode("aggregate",$3); }
| '(' '[' m_expr_list ']' ')'
{ $$=mkefuncallnode("aggregate_mapping",$3); };
| F_MULTISET_START expr_list F_MULTISET_END
{ $$=mkefuncallnode("aggregate_multiset",$2); }
| expr4 F_ARROW F_IDENTIFIER
{
$$=mknode(F_INDEX,$1,mkstrnode($3));
free_string($3);
}
;
idents: F_IDENTIFIER
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
int i;
struct efun *f;
if((i=islocal($1))>=0)
{
$$=mklocalnode(i);
}else if((i=isidentifier($1))>=0){
$$=mkidentifiernode(i);
}else if((f=lookup_efun($1))){
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | $$=mkconstantsvaluenode(&f->function);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | }else{
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | my_yyerror("'%s' undefined.",$1->str);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | $$=0;
}
free_string($1);
}
| F_PREDEF F_COLON_COLON F_IDENTIFIER
{
struct efun *f;
f=lookup_efun($3);
if(!f)
{
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | my_yyerror("Unknown efun: %s.",$3->str);
$$=mkintnode(0);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | }else{
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | $$=mksvaluenode(&f->function);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | }
free_string($3);
}
| F_IDENTIFIER F_COLON_COLON F_IDENTIFIER
{
int f;
struct reference *idp;
setup_fake_program();
f=reference_inherited_identifier($1,$3);
idp=fake_program.identifier_references+f;
if (f<0 || ID_FROM_PTR(&fake_program,idp)->func.offset == -1)
{
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | my_yyerror("Undefined identifier %s::%s", $1->str,$3->str);
$$=mkintnode(0);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | } else {
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | $$=mkidentifiernode(f);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | }
free_string($1);
free_string($3);
}
| F_COLON_COLON F_IDENTIFIER
{
int e,i;
$$=0;
setup_fake_program();
for(e=1;e<(int)fake_program.num_inherits;e++)
{
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | if(fake_program.inherits[e].inherit_level!=1) continue;
i=low_reference_inherited_identifier(e,$2);
if(i==-1) continue;
if($$)
{
$$=mknode(F_ARG_LIST,$$,mkidentifiernode(i));
}else{
$$=mkidentifiernode(i);
}
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | }
if(!$$)
{
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | $$=mkintnode(0);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | }else{
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | if($$->token==F_ARG_LIST) $$=mkefuncallnode("aggregate",$$);
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | }
free_string($2);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
comma_expr_or_zero: /* empty */ { $$=mkintnode(0); }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | comma_expr
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
comma_expr_or_maxint: /* empty */ { $$=mkintnode(0x7fffffff); }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | comma_expr
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
gauge: F_GAUGE catch_arg
{
$$=mkopernode("`-",
mkopernode("`-",
mknode(F_INDEX,mkefuncallnode("rusage",0),
mkintnode(GAUGE_RUSAGE_INDEX)),
mknode(F_ARG_LIST,$2,
mknode(F_INDEX,mkefuncallnode("rusage",0),
mkintnode(GAUGE_RUSAGE_INDEX)))),0);
} ;
typeof: F_TYPEOF '(' expr0 ')'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
node *tmp;
tmp=mknode(F_ARG_LIST,$3,0);
$$=mkstrnode(describe_type($3->type));
free_node(tmp);
} ;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | catch_arg: '(' comma_expr ')' { $$=$2; }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | block
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | catch: F_CATCH catch_arg { $$=mknode(F_CATCH,$2,NULL); } ;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
sscanf: F_SSCANF '(' expr0 ',' expr0 lvalue_list ')'
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | {
$$=mknode(F_SSCANF,mknode(F_ARG_LIST,$3,$5),$6);
}
;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
|
3ddb53 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | lvalue: expr4
| type F_IDENTIFIER
{
add_local_name($2,pop_type());
$$=mklocalnode(islocal($2));
}
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | | lvalue_list: /* empty */ { $$ = 0; }
|
3ddb53 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | ',' lvalue lvalue_list { $$ = mknode(F_LVALUE_LIST,$2,$3); }
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | ;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
low_string: F_STRING
|
7e5057 | 1996-11-02 | Fredrik Hübinette (Hubbe) | | | low_string F_STRING
{
$$=add_shared_strings($1,$2);
free_string($1);
free_string($2);
}
;
string: low_string { $$=mkstrnode($1); free_string($1); } ;
|
215bed | 1996-09-28 | Fredrik Hübinette (Hubbe) | |
%%
void yyerror(char *str)
{
extern int num_parse_error;
if (num_parse_error > 5) return;
num_parse_error++;
if ( get_master() )
{
sp->type = T_STRING;
copy_shared_string(sp->u.string, current_file);
sp++;
sp->type = T_INT;
sp->u.integer = current_line;
sp++;
sp->type = T_STRING;
sp->u.string = make_shared_string(str);
sp++;
SAFE_APPLY_MASTER("compile_error",3);
pop_stack();
}else{
(void)fprintf(stderr, "%s:%ld: %s\n",
current_file->str,
(long)current_line,
str);
fflush(stderr);
}
}
/* argument must be a shared string (no need to free it) */
void add_local_name(struct pike_string *str,
struct pike_string *type)
{
if (local_variables->current_number_of_locals == MAX_LOCAL)
{
yyerror("Too many local variables");
}else {
local_variables->variable[local_variables->current_number_of_locals].type = type;
local_variables->variable[local_variables->current_number_of_locals].name = str;
local_variables->current_number_of_locals++;
if(local_variables->current_number_of_locals >
local_variables->max_number_of_locals)
{
local_variables->max_number_of_locals=
local_variables->current_number_of_locals;
}
}
}
/* argument must be a shared string */
int islocal(struct pike_string *str)
{
int e;
for(e=local_variables->current_number_of_locals-1;e>=0;e--)
if(local_variables->variable[e].name==str)
return e;
return -1;
}
void free_all_local_names()
{
int e;
for (e=0; e<local_variables->current_number_of_locals; e++)
{
if(local_variables->variable[e].name)
{
free_string(local_variables->variable[e].name);
free_string(local_variables->variable[e].type);
}
local_variables->variable[e].name=0;
local_variables->variable[e].type=0;
}
local_variables->current_number_of_locals = 0;
local_variables->max_number_of_locals = 0;
}
static void push_locals()
{
struct locals *l;
l=ALLOC_STRUCT(locals);
l->current_type=0;
l->current_return_type=0;
l->next=local_variables;
l->current_number_of_locals=0;
l->max_number_of_locals=0;
local_variables=l;
}
static void pop_locals()
{
struct locals *l;
free_all_local_names();
l=local_variables->next;
if(local_variables->current_type)
free_string(local_variables->current_type);
if(local_variables->current_return_type)
free_string(local_variables->current_return_type);
free((char *)local_variables);
local_variables=l;
/* insert check if ( local->next == parent locals ) here */
}
|