%{ #if (defined(__CYGWIN__)) || defined(__MINGW32__) /* missing from rpcgen generated .h on CygWin: */ #define bool_t int #define u_int unsigned int #endif #ifdef RPCGEN_HEADERS #include "npcode.h" #else #include "npcode.xs.h" #endif #include #include #include "npcode_defs.h" #include "a4gl_memhandling.h" int while_cnt=0; int if_cnt=0; int while_stack[256]; int while_stack_cnt=0; static int if_stack[256]; static int if_stack_cnt=0; static char buff[20]; extern module *this_module_ptr; void make_named_struct (char *name, struct define_variables *v); %} %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF %token AND_OP %token OR_OP %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP %token MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN %token XOR_ASSIGN OR_ASSIGN TYPE_NAME FGLDATE FGLDECIMAL FGLMONEY FGLSDTIME %type variable %type param dtype %token TYPEDEF EXTERN STATIC AUTO REGISTER %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID %token STRUCT UNION ENUM ELLIPSIS FUNCTION %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN %token ON_KEY BEF_ROW AFT_ROW AFTER_INP %token KW_A_PUSH_LONG %token KW_A_PUSH_INT %token KW_A_PUSH_CHAR %token KW_A_PUSH_OP %token KW_A_CHK_ERR %token KW_A_CLR_ERR %token KW_A_ERRCHK %token KW_A_ECALL %token KW_A_SET_STAT %token KW_A_SETLINE %token KW_A_POP_VAR2 %token KW_A_POP_FUNCTION %token KW_A_PUSH_FUNCTION %token KW_A_POP_ARGS %token KW_A_POP_PARAMS %token KW_A_PUSH_VARIABLE %token KW_A_SUBSTR %start translation_unit %name-prefix="pcode_yy" %union { char str[10000]; struct cmd *cmd; void *ptr; long e_id; int i; struct variable_element *define_var; struct use_variable *use_var; struct define_variables *define_variables; struct s_assign assignment; struct char_list clist; } %% translation_unit : tu | translation_unit tu ; tu : function_definition | define_entry_op_set ; op_function: | FUNCTION ; function_definition : op_function IDENTIFIER '(' fparm ')' '{' { add_function($2,$4,0); } func_block { end_function(); } | op_function STATIC IDENTIFIER '(' fparm ')' '{' { add_function($3,$5,1); } func_block { end_function(); } | op_function STATIC dtype IDENTIFIER '(' fparm ')' '{' { add_function($4,$6,1); } func_block { end_function(); } | op_function dtype IDENTIFIER '(' fparm ')' '{' { add_function($3,$5,0); } func_block { end_function(); } | op_function dtype IDENTIFIER '(' VOID ')' '{' { add_function($3,0,0); } func_block { end_function(); } | op_function STATIC dtype IDENTIFIER '(' VOID ')' '{' { add_function($4,0,1); } func_block { end_function(); } | op_function STATIC IDENTIFIER '(' VOID ')' '{' { add_function($3,0,1); } func_block { end_function(); } | op_function dtype IDENTIFIER '(' ')' '{' { add_function($3,0,0); } func_block { end_function(); } | op_function STATIC dtype IDENTIFIER '(' ')' '{' { add_function($4,0,1); } func_block { end_function(); } | op_function STATIC IDENTIFIER '(' ')' '{' { add_function($3,0,1); } func_block { end_function(); } ; op_cmds: | cmds ; cmds : cmd | cmd cmds ; cmd : ';' /* Nothing... */ | block | if | for | while | goto ';' | label | assign ';' | fcall ';' | break ';' | continue ';' | return ';' | expr ';' /* 4GL specific shortcuts */ | fgl_funcs ; typedef_decl: TYPEDEF dtype IDENTIFIER { printf("Adding : %s\n",$3); make_named_struct ($3, $2); printf("Added %s\n",$3); } ; a4gl_sub: KW_A_SUBSTR '(' op_expr_list ')' { $$=new_param_fcall_returns_long($1,$3); } ; fgl_funcs : a4gl_sub { add_push_substr($1); } |KW_A_PUSH_LONG '(' int_constant_val ')' { add_push_long(atoi($3)); } | KW_A_POP_ARGS '(' variable ')' { add_pop_args($3); } | KW_A_POP_FUNCTION '(' ')' { add_pop_function(); } | KW_A_POP_VAR2 '(' variable ',' int_constant_val ',' int_constant_val ')' | KW_A_PUSH_FUNCTION '(' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' | KW_A_POP_PARAMS '(' variable ',' int_constant_val ')' | KW_A_PUSH_VARIABLE '(' variable ',' int_constant_val ')' | KW_A_PUSH_INT '(' int_constant_val ')' { add_push_int(atoi($3)); } | KW_A_PUSH_CHAR '(' STRING_LITERAL ')' { add_push_char($3); } | KW_A_PUSH_OP '(' CONSTANT ')' { add_push_op($3); } | KW_A_SET_STAT '(' int_constant_val ',' int_val ')' { add_set_stat(atoi($3)); } | KW_A_SETLINE '(' int_val ',' int_val ')' { add_set_line("",atoi($5)); } | KW_A_SETLINE '(' IDENTIFIER ',' int_val ')' { add_set_line($3,atoi($5)); } | KW_A_SETLINE '(' STRING_LITERAL ',' int_val ')' { add_set_line($3,atoi($5)); } | KW_A_ECALL '(' STRING_LITERAL ',' int_val ',' int_val ')' { //printf("ECALL....\n"); add_ecall($3, get_expr_n($5),get_expr_n($7)); } | KW_A_PUSH_CHAR '(' variable ')' { add_push_charv($3); } | KW_A_PUSH_CHAR '(' a4gl_sub ')' { add_push_charv($3); } | KW_A_CHK_ERR '(' int_val ',' IDENTIFIER ')' { add_chk_err(get_expr_n($3)); } | KW_A_CHK_ERR '(' int_val ',' STRING_LITERAL ')' { add_chk_err(get_expr_n($3)); } | KW_A_CLR_ERR '(' ')' { add_clr_err(); } | KW_A_ERRCHK '(' int_val ',' STRING_LITERAL ',' int_val ',' STRING_LITERAL ',' int_val ',' STRING_LITERAL ',' int_val ',' STRING_LITERAL ',' int_val ',' STRING_LITERAL ',' int_val ',' STRING_LITERAL ')' { struct cmd_errchk *ptr; struct cmd_errchk_40110 *ptr_40110; struct cmd_errchk_40010 *ptr_40010; struct cmd_errchk_40000 *ptr_40000; int added=0; ptr=acl_malloc2(sizeof(struct cmd_errchk)); ptr_40110=acl_malloc2(sizeof(struct cmd_errchk_40110)); ptr_40010=acl_malloc2(sizeof(struct cmd_errchk_40010)); ptr_40000=acl_malloc2(sizeof(struct cmd_errchk_40000)); memset(ptr,0,sizeof(struct cmd_errchk)); memset(ptr_40110,0,sizeof(struct cmd_errchk_40110)); memset(ptr_40010,0,sizeof(struct cmd_errchk_40010)); memset(ptr_40000,0,sizeof(struct cmd_errchk_40000)); ptr->line=get_expr_n($3); ptr->module_name=add_string($5); ptr_40110->line=get_expr_n($3); ptr_40110->module_name=add_string($5); ptr_40010->line=get_expr_n($3); ptr_40010->module_name=add_string($5); ptr_40000->line=get_expr_n($3); ptr_40000->module_name=add_string($5); ptr->modes[0]=get_expr_n($7); ptr->modes[1]=get_expr_n($11); ptr->modes[2]=get_expr_n($15); ptr->modes[3]=get_expr_n($19); ptr->modes[4]=get_expr_n($23); ptr->actions[0]=add_string($9); ptr->actions[1]=add_string($13); ptr->actions[2]=add_string($17); ptr->actions[3]=add_string($21); ptr->actions[4]=add_string($25); if (ptr->modes[0]==4 && ptr->modes[1]==0 && ptr->modes[2]==1 && ptr->modes[3]==1 && ptr->modes[4]==0 ) { add_errchk_40110(ptr_40110); added=1; } if (ptr->modes[0]==4 && ptr->modes[1]==0 && ptr->modes[2]==0 && ptr->modes[3]==1 && ptr->modes[4]==0 ) { add_errchk_40010(ptr_40010); added=1; } if (ptr->modes[0]==4 && ptr->modes[1]==0 && ptr->modes[2]==0 && ptr->modes[3]==0 && ptr->modes[4]==0 ) { add_errchk_40000(ptr_40000); added=1; } if (!added) { add_errchk(ptr); } } ; break: BREAK { add_break(while_stack[while_stack_cnt-1]); } ; continue: CONTINUE { add_continue(while_stack[while_stack_cnt-1]); } ; fparm: {$$=0;} | has_fparam {$$=$1;} ; has_fparam: param { $$=acl_malloc2(sizeof(struct define_variables)); $$->var_len=1; $$->var_val=acl_malloc2(sizeof(struct variable_element)); memcpy(&$$->var_val[0],$1,sizeof(struct variable_element)); } | has_fparam ',' param { struct define_variables *v; v=$1; v->var_len++; v->var_val=realloc(v->var_val, sizeof(struct variable_element)*v->var_len); memcpy(&v->var_val[v->var_len-1],$3,sizeof(struct variable_element)); } ; has_structparam: param_semi { struct define_variables *v; v=acl_malloc2(sizeof(struct define_variables)); v->var_len=1; v->var_val=acl_malloc2(sizeof(struct variable_element)); memcpy(&v->var_val[0],$1,sizeof(struct variable_element)); $$=v; } | has_structparam param_semi { struct define_variables *v; //char buff[80]; v=$1; v->var_len++; v->var_val=realloc(v->var_val, sizeof(struct variable_element)*v->var_len); A4GL_debug("Name = %d\n",$2->name_id); memcpy(&v->var_val[v->var_len-1],$2,sizeof(struct variable_element)); $$=v; } ; param_semi : param ';' {$$=$1;} ; param : dtype id_list {$$=$1; $$->name_id=add_id($2); } | dtype id_list '[' dtype_int_val ']' { long x; $$=$1; $$->name_id=add_id($2); evaluate_param_i_into_integer($4,&x); $$->i_arr_size[0]=x; $$->i_arr_size[1]=0; $$->i_arr_size[2]=0; } | dtype id_list '[' dtype_int_val ']' '[' dtype_int_val ']' { long x; $$=$1; $$->name_id=add_id($2); evaluate_param_i_into_integer($4,&x); $$->i_arr_size[0]=x; evaluate_param_i_into_integer($7,&x); $$->i_arr_size[1]=x; $$->i_arr_size[2]=0; } | dtype id_list '[' dtype_int_val ']' '[' dtype_int_val ']' '[' dtype_int_val ']' { long x; $$=$1; $$->name_id=add_id($2); evaluate_param_i_into_integer($4,&x); $$->i_arr_size[0]=x; evaluate_param_i_into_integer($7,&x); $$->i_arr_size[1]=x; evaluate_param_i_into_integer($10,&x); $$->i_arr_size[2]=x; } | dtype id_list '[' ']' { //struct param *sz; $$=$1; $$->name_id=add_id($2); $$->i_arr_size[0]=-1; } ; id_list : IDENTIFIER ; define: {end_define();} | has_define {end_define();} ; has_define: define_entry_op_set | has_define define_entry_op_set ; define_entry_op_set: define_entry ';' {set_type(0);} | typedef_decl ';' {set_type(0);} ; op_set : | set {set_master_set($1);} ; return: RETURN {add_return(0);} | RETURN expr {add_return($2);} ; set: '=' set_internal { $$=$2; } ; set_internal: expr {$$=$1;} | '{' s_expr_list '}' { $$=$2; } | '{' '}' { $$=0; } ; s_expr_list : set_internal {$$=new_param_list_returns_long($1);} | s_expr_list ',' set_internal {append_param_list($1,$3);$$=$1;} ; define_qualifier : STATIC {$$=CAT_STATIC;set_type(1);} | EXTERN {$$=CAT_EXTERN;set_type(2);} ; define_entry: opd_define_entry op_set { set_master_type(CAT_NORMAL); } | qualified opd_define_entry op_set { set_master_type($1); } ; qualified : define_qualifier {$$=$1;} | qualified define_qualifier {$$=$1|$2;} ; opd_define_entry: /* Variable definitions */ dtype IDENTIFIER {add_variable(0,$1,$2,0);} | dtype IDENTIFIER '[' ']' { long as[3]; as[0]=-1; as[1]=0; as[2]=0; add_variable_array(0,$1,$2,as,0); } | dtype IDENTIFIER '[' dtype_int_val ']' { long as[3]; long x; evaluate_param_i_into_integer($4,&x); as[0]=x; as[1]=0; as[2]=0; add_variable_array(0,$1,$2,as,0); } | dtype IDENTIFIER '[' dtype_int_val ']' '[' dtype_int_val ']' { long as[3]; long x; evaluate_param_i_into_integer($4,&x); as[0]=x; evaluate_param_i_into_integer($7,&x); as[1]=x; as[2]=0; add_variable_array(0,$1,$2,as,0); } | dtype IDENTIFIER '[' dtype_int_val ']' '[' dtype_int_val ']' '[' dtype_int_val ']' { long as[3]; long x; evaluate_param_i_into_integer($4,&x); as[0]=x; evaluate_param_i_into_integer($7,&x); as[1]=x; evaluate_param_i_into_integer($10,&x); as[2]=x; add_variable_array(0,$1,$2,as,0); } ; dtype_int_val : int_val {$$=$1;} | int_val '+' int_val { int n; n=get_expr_n($1) + get_expr_n($3); $$=new_param_returns_long('I',(void *)n); } ; dtype : CHAR {$$=new_variable_element_string("CHAR");} | SIGNED CHAR {$$=new_variable_element_string("CHAR");} | UNSIGNED CHAR {$$=new_variable_element_string("UCHAR");} | SHORT {$$=new_variable_element_string("SHORT");} | SHORT INT {$$=new_variable_element_string("SHORT");} | INT {$$=new_variable_element_string("LONG");} | UNSIGNED SHORT {$$=new_variable_element_string("USHORT");} | SIGNED SHORT {$$=new_variable_element_string("SHORT");} | UNSIGNED INT {$$=new_variable_element_string("ULONG");} | SIGNED INT {$$=new_variable_element_string("LONG");} | UNSIGNED SHORT INT {$$=new_variable_element_string("USHORT");} | SIGNED SHORT INT {$$=new_variable_element_string("SHORT");} | FGLDATE {$$=new_variable_element_string("FGLDATE");} | FGLDECIMAL {$$=new_variable_element_string("FGLDECIMAL");} | FGLMONEY {$$=new_variable_element_string("FGLMONEY");} | FGLSDTIME {$$=new_variable_element_string("FGLSDTIME");} | LONG {$$=new_variable_element_string("LONG");} | LONG INT {$$=new_variable_element_string("LONG");} | UNSIGNED LONG {$$=new_variable_element_string("ULONG");} | UNSIGNED LONG INT {$$=new_variable_element_string("ULONG");} | LONG LONG {$$=new_variable_element_string("LONGLONG");} | SIGNED LONG LONG {$$=new_variable_element_string("LONGLONG");} | UNSIGNED LONG LONG {$$=new_variable_element_string("ULONGLONG");} | LONG LONG INT {$$=new_variable_element_string("LONGLONG");} | SIGNED LONG LONG INT {$$=new_variable_element_string("LONGLONG");} | UNSIGNED LONG LONG INT {$$=new_variable_element_string("ULONGLONG");} | FLOAT {$$=new_variable_element_string("FLOAT");} | DOUBLE {$$=new_variable_element_string("DOUBLE");} | VOID {$$=new_variable_element_string("Void");} | CHAR '*' {$$=new_variable_element_string("String");} | INT '*' {$$=new_variable_element_string("LongPtr");} | LONG '*' {$$=new_variable_element_string("LongPtr");} | SHORT '*' {$$=new_variable_element_string("ShortPtr");} | VOID '*' {$$=new_variable_element_string("VoidPointer");} | VOID '*' '*' {$$=new_variable_element_string("VoidPointer");} | VOID '*' '*' '*' {$$=new_variable_element_string("VoidPointer");} | STRUCT struct_has_define {$$=new_variable_struct($2); } | TYPE_NAME { struct define_variables *v; struct variable_element *e; v=add_named_struct($1); printf("v=%p\n",v); e=new_variable_struct(v); printf("e=%p\n",e); $$=e; printf("Get : %p\n",$$); } ; struct_has_define: IDENTIFIER { $$=(struct define_variables *)add_named_struct($1); } | TYPE_NAME {$$=(struct define_variables *)add_named_struct($1);} | '{' has_structparam '}' { A4GL_debug("Structure : %p\n",$2); $$=$2; A4GL_debug("BBB : %p from %p\n",$$,$2); } ; func_block : define op_cmds '}' ; block : '{' { add_block(0); set_pc_vstack_curr(); } define op_cmds '}' {end_block();} | '{' '}' {add_block(0); set_pc_vstack_curr(); end_block(); } ; if: IF '(' expr ')' { if_cnt++; if_stack[if_stack_cnt++]=if_cnt; $$=if_cnt; sprintf(buff,"_if_c_%d",if_cnt); A4GL_debug("i = %d\n",$$); add_label(buff); sprintf(buff,"_if_else_%d",if_cnt); add_if($3,0,acl_strdup(buff)); } cmd { A4GL_debug("using i = %d\n",$5); sprintf(buff,"_if_end_%d",$5); add_goto(buff); sprintf(buff,"_if_else_%d",$5); add_label(buff); } op_else { sprintf(buff,"_if_end_%d",$5); add_label(buff); if_stack_cnt--; } ; op_else: | ELSE cmd ; for : FOR '(' assign ';' { while_cnt++; while_stack[while_stack_cnt++]=while_cnt; $$=while_cnt; sprintf(buff,"_while_c_%d",while_cnt); add_label(buff); } expr ';' { sprintf(buff,"_while_e_%d",$5); add_if($6,0,acl_strdup(buff)); } assign_common ')' cmd { add_set_var($9.v,$9.p,0,0,0); sprintf(buff,"_while_c_%d",$5); add_goto(buff); sprintf(buff,"_while_e_%d",$5); add_label(buff); while_stack_cnt--; } ; while : WHILE { while_cnt++; while_stack[while_stack_cnt++]=while_cnt; $$=while_cnt; sprintf(buff,"_while_c_%d",while_cnt); add_label(buff); } '(' expr ')' { sprintf(buff,"_while_e_%d",$2); add_if($4,0,acl_strdup(buff)); } cmd { sprintf(buff,"_while_c_%d",$2); add_goto(buff); sprintf(buff,"_while_e_%d",$2); add_label(buff); while_stack_cnt--; } ; label : IDENTIFIER ':' cmd { add_label($1); } ; goto: GOTO IDENTIFIER { add_goto($2); } ; expr : or_expr {$$=$1;} ; or_expr: and_expr {$$=$1;} | or_expr OR_OP and_expr { $$=new_param_op_returns_long($1,$2,$3); } ; and_expr : other_expr_1 {$$=$1;} | and_expr AND_OP other_expr_1 { $$=new_param_op_returns_long($1,$2,$3); } ; other_expr_1: expr_1 ; expr_1: op {$$=$1; } | int_val {$$=$1;} | STRING_LITERAL { char *buff; char *buff2; buff=acl_strdup($1); buff2=&buff[1]; buff2[strlen(buff2)-1]=0; $$=new_param_returns_long('s',buff2); free(buff); } | fcall_expr {$$=$1; } | variable {$$=$1; } | '(' expr ')' {$$=$2; } | cast expr {$$=$2; } | '!' expr {$$=new_param_op_returns_long($2,"NOT",0);} | BEF_ROW { $$=new_param_returns_long('S',"BEF_ROW");} | AFT_ROW { $$=new_param_returns_long('S',"AFT_ROW");} | AFTER_INP { $$=new_param_returns_long('S',"AFTER_INP");} | ON_KEY '(' STRING_LITERAL ')' { $$=new_param_returns_long('K',$3);} ; cast: '(' dtype ')' ; op_expr_list : {$$=0; } | expr_list {$$=$1;} ; expr_list: expr {$$=new_param_list_returns_long($1); } | expr_list ',' expr { append_param_list($1,$3); $$=$1; } ; fcall : IDENTIFIER '(' op_expr_list ')' { add_call($1,$3); } ; fcall_expr : IDENTIFIER '(' op_expr_list ')' { $$=new_param_fcall_returns_long($1,$3); } | SIZEOF '(' op_expr_list ')' { $$=new_param_fcall_returns_long($1,$3); } ; op: expr_1 double_operator expr_1 { $$=new_param_op_returns_long($1,$2,$3); } ; double_operator: LE_OP | GE_OP | EQ_OP | NE_OP | '+' | '-' | '*' | '%' | '/' | '<' | '>' ; int_constant_val : CONSTANT | '+' CONSTANT {sprintf($$,"%s",$2);} | '-' CONSTANT {sprintf($$,"-%s",$2);} ; int_val: int_constant_val { char buff[256]; unsigned long n=0; strcpy(buff,$1); if (buff[0]=='0') { if (buff[1]=='x'||buff[1]=='X') { if (strcmp(buff,"0xffffffff")==0) { n=0xffffffff; } else { n=strtol(buff,0,16); } } else { n=strtol(buff,0,8); } } else { n=atoi($1); } $$=new_param_returns_long('I',(void *)n); } ; assign: assign_common { add_set_var($1.v,$1.p,0,0,0); } ; assign_common: variable '=' expr { struct param *e; struct use_variable *v; e=&PARAM_ID(this_module_ptr,$1); v=get_use_variable($1); $$.p=$3; $$.v=v; } | variable INC_OP { int e_id2; int n; n=new_param_returns_long('I',(void *)1); e_id2=new_param_op_returns_long($1,"+",n); $$.p=e_id2; $$.v=get_use_variable($1); } | variable DEC_OP { int e_id2; int n; n=new_param_returns_long('I',(void *)1); e_id2=new_param_op_returns_long($1,"-",n); $$.p=e_id2; $$.v=get_use_variable($1); } | variable ADD_ASSIGN expr { long e2; e2=new_param_op_returns_long($1,"+",$3); $$.p=e2; $$.v=get_use_variable($1); } | variable SUB_ASSIGN expr { long e2; e2=new_param_op_returns_long($1,"-",$3); $$.p=e2; $$.v=get_use_variable($1); } | variable MUL_ASSIGN expr { long e2; e2=new_param_op_returns_long($1,"*",$3); $$.p=e2; $$.v=get_use_variable($1); } | variable DIV_ASSIGN expr { long e2; e2=new_param_op_returns_long($1,"/",$3); $$.p=e2; $$.v=get_use_variable($1); } ; variable: IDENTIFIER { $$=new_param_returns_long('V',(void *)mk_use_variable(0 ,0, 0,0, $1,0)); } | IDENTIFIER '[' expr ']' { $$=new_param_returns_long('V',(void *)mk_use_variable(0,$3,0,0,$1,0)); } | IDENTIFIER '[' expr ']' '[' expr ']' { $$=new_param_returns_long('V',(void *)mk_use_variable(0,$3,$6,0,$1,0)); } | IDENTIFIER '[' expr ']' '[' expr ']' '[' expr ']' { $$=new_param_returns_long('V',(void *)mk_use_variable(0,$3,$6,$9,$1,0)); } | variable '.' IDENTIFIER { $$=new_param_returns_long('V', (void *)mk_use_variable( $1, 0 ,0,0, $3,0)); } | variable '.' IDENTIFIER '[' expr ']' { $$=new_param_returns_long('V',(void *)mk_use_variable( $1, $5, 0,0, $3, 0)); } | '*' variable { $$=$2; set_indirection($2,1); } | '&' variable { set_indirection($2,-1); $$=$2; } ;