home *** CD-ROM | disk | FTP | other *** search
- From: brennan@ssc-vax.UUCP (Mike Brennan)
- Newsgroups: alt.sources
- Subject: mawk0.97.shar 2 of 6
- Message-ID: <3964@ssc-bee.ssc-vax.UUCP>
- Date: 11 May 91 14:51:06 GMT
-
-
- ------------------cut here----------------
- { case C_NOINIT : cp->dval = 0.0 ; break ;
-
- case C_DOUBLE : goto two ;
- case C_STRNUM :
- free_STRING( string(cp) ) ;
- break ;
-
- case C_MBSTRN :
- case C_STRING :
- s = (STRING *) cp->ptr ;
-
- #if FPE_TRAPS /* look for overflow error */
- errno = 0 ;
- cp->dval = strtod(s->str,(char **)0) ;
- if ( errno && cp->dval != 0.0 ) /* ignore underflow */
- rt_error("overflow converting %s to double", s) ;
- #else
- cp->dval = strtod(s->str,(char **)0) ;
- #endif
- free_STRING(s) ;
- break ;
-
- default :
- bozo("cast on bad type") ;
- }
- cp->type = C_DOUBLE ;
-
- two: cp++ ;
- switch( cp->type )
- { case C_NOINIT : cp->dval = 0.0 ; break ;
-
- case C_DOUBLE : return ;
- case C_STRNUM :
- free_STRING( string(cp) ) ;
- break ;
-
- case C_MBSTRN :
- case C_STRING :
- s = (STRING *) cp->ptr ;
-
- #if FPE_TRAPS /* look for overflow error */
- errno = 0 ;
- cp->dval = strtod(s->str,(char **)0) ;
- if ( errno && cp->dval != 0.0 ) /* ignore underflow */
- rt_error("overflow converting %s to double", s) ;
- #else
- cp->dval = strtod(s->str,(char **)0) ;
- #endif
- free_STRING(s) ;
- break ;
-
- default :
- bozo("cast on bad type") ;
- }
- cp->type = C_DOUBLE ;
- }
-
- void cast1_to_s( cp )
- register CELL *cp ;
- {
- switch( cp->type )
- { case C_NOINIT :
- null_str.ref_cnt++ ;
- cp->ptr = (PTR) &null_str ;
- break ;
-
- case C_DOUBLE :
- (void) sprintf(temp_buff.string_buff ,
- string(field+OFMT)->str, cp->dval) ;
-
- cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
- break ;
-
- case C_STRING : return ;
-
- case C_MBSTRN :
- case C_STRNUM : break ;
-
- default : bozo("bad type on cast") ;
- }
- cp->type = C_STRING ;
- }
-
- void cast2_to_s( cp )
- register CELL *cp ;
- {
-
- switch( cp->type )
- { case C_NOINIT :
- null_str.ref_cnt++ ;
- cp->ptr = (PTR) &null_str ;
- break ;
-
- case C_DOUBLE :
- (void) sprintf(temp_buff.string_buff,
- string(field+OFMT)->str, cp->dval ) ;
-
- cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
- break ;
-
- case C_STRING : goto two ;
-
- case C_MBSTRN :
- case C_STRNUM : break ;
-
- default : bozo("bad type on cast") ;
- }
- cp->type = C_STRING ;
-
- two:
- cp++ ;
-
- switch( cp->type )
- { case C_NOINIT :
- null_str.ref_cnt++ ;
- cp->ptr = (PTR) &null_str ;
- break ;
-
- case C_DOUBLE :
- (void) sprintf(temp_buff.string_buff,
- string(field+OFMT)->str, cp->dval) ;
-
- cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
- break ;
-
- case C_STRING : return ;
-
- case C_MBSTRN :
- case C_STRNUM : break ;
-
- default : bozo("bad type on cast") ;
- }
- cp->type = C_STRING ;
- }
-
- void cast_to_RE( cp )
- register CELL *cp ;
- { register PTR p ;
-
- if ( cp->type < C_STRING ) cast1_to_s(cp) ;
-
- p = re_compile( string(cp) ) ;
- free_STRING( string(cp) ) ;
- cp->type = C_RE ;
- cp->ptr = p ;
-
- }
-
- void cast_for_split(cp)
- register CELL *cp ;
- {
- static char meta[] = "^$.*+?|[]()" ;
- static char xbuff[] = "\\X" ;
- int c ;
- unsigned len ;
-
- if ( cp->type < C_STRING ) cast1_to_s(cp) ;
-
- if ( (len = string(cp)->len) == 1 )
- {
- if ( (c = string(cp)->str[0]) == ' ' )
- { free_STRING(string(cp)) ;
- cp->type = C_SPACE ;
- return ;
- }
- else
- if ( strchr(meta, c) )
- { xbuff[1] = c ;
- free_STRING(string(cp)) ;
- cp->ptr = (PTR) new_STRING(xbuff) ;
- }
- }
- else
- if ( len == 0 )
- { free_STRING(string(cp)) ;
- cp->type = C_SNULL ;
- return ;
- }
-
- cast_to_RE(cp) ;
- }
-
- /* input: cp-> a CELL of type C_MBSTRN (maybe strnum)
- test it -- casting it to the appropriate type
- which is C_STRING or C_STRNUM
- */
-
- void check_strnum( cp )
- CELL *cp ;
- { char *test ;
- register unsigned char *s , *q ;
-
- cp->type = C_STRING ; /* assume not C_STRNUM */
- s = (unsigned char *) string(cp)->str ;
- q = s + string(cp)->len ;
- while ( scan_code[*s] == SC_SPACE ) s++ ;
- if ( s == q ) return ;
-
- while ( scan_code[ q[-1] ] == SC_SPACE ) q-- ;
- if ( scan_code[ q[-1] ] != SC_DIGIT &&
- q[-1] != '.' ) return ;
-
- switch ( scan_code[*s] )
- {
- case SC_DIGIT :
- case SC_PLUS :
- case SC_MINUS :
- case SC_DOT :
-
- #if FPE_TRAPS
- errno = 0 ;
- cp->dval = strtod((char *)s, &test) ;
- if ( errno && cp->dval != 0.0 )
- rt_error(
- "overflow converting %s to double" , s) ;
- #else
- cp->dval = strtod(s, &test) ;
- #endif
-
- if ((char *) q == test ) cp->type = C_STRNUM ;
- }
- }
-
- /* cast a CELL to a replacement cell */
-
- void cast_to_REPL( cp )
- register CELL *cp ;
- { register STRING *sval ;
-
- if ( cp->type < C_STRING ) cast1_to_s(cp) ;
- sval = (STRING *) cp->ptr ;
-
- (void) cellcpy(cp, repl_compile(sval)) ;
- free_STRING(sval) ;
- }
-
-
- #if NO_STRTOD
-
- static char d_str[] =
- "^[ \t]*[-+]?([0-9]+\\.?|\\.[0-9])[0-9]*([eE][-+]?[0-9]+)?" ;
-
- static PTR d_ptr ;
-
- void strtod_init()
- { STRING *sval = new_STRING(d_str) ;
-
- d_ptr = re_compile(sval) ;
- free_STRING(sval) ;
- }
-
- double strtod( s, endptr)
- char *s , **endptr ;
- { double atof() ;
-
- if ( endptr )
- { unsigned len ;
-
- (void) REmatch(s, d_ptr, &len) ;
- *endptr = s + len ;
- }
- return atof(s) ;
- }
- #endif /* NO_STRTOD */
-
- #if NO_FMOD
-
- double fmod(x, y)
- double x, y ;
- { double modf() ;
- double ipart ;
-
- return modf(x/y, &ipart) * y ;
- }
-
- #endif /* NO_FMOD */
-
-
-
- @//E*O*F mawk0.97/cast.c//
- chmod u=rw,g=r,o=r mawk0.97/cast.c
-
- echo x - mawk0.97/code.c
- sed 's/^@//' > "mawk0.97/code.c" <<'@//E*O*F mawk0.97/code.c//'
-
- /********************************************
- code.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /* $Log: code.c,v $
- * Revision 2.1 91/04/08 08:22:46 brennan
- * VERSION 0.97
- *
- */
-
- /* code.c */
-
- #include "mawk.h"
- #include "code.h"
- #include "init.h"
-
-
- #define CODE_SZ (PAGE_SZ*sizeof(INST))
-
- INST *code_ptr ;
- INST *main_start , *main_code_ptr ;
- INST *begin_start , *begin_code_ptr ;
- INST *end_start , *end_code_ptr ;
- unsigned main_size, begin_size, end_size ;
-
- void PROTO(fdump, (void) ) ;
-
- void code_init()
- {
- main_code_ptr = main_start = (INST *) zmalloc(CODE_SZ) ;
- begin_code_ptr = begin_start = (INST *) zmalloc(CODE_SZ) ;
- end_code_ptr = end_start = (INST *) zmalloc(CODE_SZ) ;
- code_ptr = main_code_ptr ;
- }
-
- void code_cleanup()
- {
- if ( dump_code ) fdump() ; /* dumps all functions */
-
- begin_code_ptr++->op = _HALT ;
- if ( (begin_size = begin_code_ptr - begin_start) == 1 ) /* empty */
- {
- zfree( begin_start, CODE_SZ ) ;
- begin_start = (INST *) 0 ;
- }
- else
- if ( begin_size > PAGE_SZ ) overflow("BEGIN code" , PAGE_SZ) ;
- else
- { begin_size *= sizeof(INST) ;
- begin_start = (INST *) zrealloc(begin_start,CODE_SZ,begin_size) ;
- if ( dump_code )
- { fprintf(stderr, "BEGIN\n") ;
- da(begin_start, stderr) ;
- }
- }
-
- end_code_ptr++->op = _HALT ;
- if ( (end_size = end_code_ptr - end_start) == 1 ) /* empty */
- {
- zfree( end_start, CODE_SZ ) ;
- end_start = (INST *) 0 ;
- }
- else
- if ( end_size > PAGE_SZ ) overflow("END code" , PAGE_SZ) ;
- else
- { end_size *= sizeof(INST) ;
- end_start = (INST *) zrealloc(end_start, CODE_SZ, end_size) ;
- if ( dump_code )
- { fprintf(stderr, "END\n") ;
- da(end_start, stderr) ;
- }
- }
-
- code_ptr++->op = _HALT ;
- if ( (main_size = code_ptr - main_start) == 1 ) /* empty */
- {
- zfree( main_start, CODE_SZ ) ;
- main_start = (INST *) 0 ;
- }
- else
- if ( main_size > PAGE_SZ ) overflow("MAIN code" , PAGE_SZ) ;
- else
- { main_size *= sizeof(INST) ;
- main_start = (INST *) zrealloc(main_start, CODE_SZ, main_size) ;
- if ( dump_code )
- { fprintf(stderr, "MAIN\n") ;
- da(main_start, stderr) ;
- }
- }
- }
- @//E*O*F mawk0.97/code.c//
- chmod u=rw,g=r,o=r mawk0.97/code.c
-
- echo x - mawk0.97/code.h
- sed 's/^@//' > "mawk0.97/code.h" <<'@//E*O*F mawk0.97/code.h//'
-
- /********************************************
- code.h
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /* $Log: code.h,v $
- * Revision 2.1 91/04/08 08:22:48 brennan
- * VERSION 0.97
- *
- */
-
-
- /* code.h */
-
- #ifndef CODE_H
- #define CODE_H
-
- #include "memory.h"
- #include <setjmp.h>
-
- /* coding scope */
- #define SCOPE_MAIN 0
- #define SCOPE_BEGIN 1
- #define SCOPE_END 2
- #define SCOPE_FUNCT 3
-
-
- extern INST *code_ptr ;
- extern INST *begin_start , *begin_code_ptr ;
- extern INST *end_start , *end_code_ptr ;
- extern INST *main_start, *main_code_ptr ;
- extern unsigned begin_size, end_size, main_size ;
-
- extern CELL eval_stack[] ;
-
-
- #define code1(x) code_ptr++ -> op = (x)
-
- #define code2(x,y) (void)( code_ptr++ -> op = (x) ,\
- code_ptr++ -> ptr = (PTR)(y) )
-
-
- /* the machine opcodes */
-
- #define _HALT 0
- #define _STOP 1
- #define _STOP0 2
- #define _PUSHC 3
- #define _PUSHINT 4
- #define _PUSHA 5
- #define _PUSHI 6
- #define L_PUSHA 7
- #define L_PUSHI 8
- #define AE_PUSHA 9
- #define AE_PUSHI 10
- #define A_PUSHA 11
- #define LAE_PUSHA 12
- #define LAE_PUSHI 13
- #define LA_PUSHA 14
- #define F_PUSHA 15
- #define FE_PUSHA 16
- #define F_PUSHI 17
- #define FE_PUSHI 18
- #define _POP 19
- #define _PULL 20
- #define _DUP 21
- #define _ADD 22
- #define _SUB 23
- #define _MUL 24
- #define _DIV 25
- #define _MOD 26
- #define _POW 27
- #define _NOT 28
- #define _TEST 29
- #define A_TEST 30
- #define A_DEL 31
- #define A_LOOP 32
- #define A_CAT 33
- #define _UMINUS 34
- #define _UPLUS 35
- #define _ASSIGN 36
- #define _ADD_ASG 37
- #define _SUB_ASG 38
- #define _MUL_ASG 39
- #define _DIV_ASG 40
- #define _MOD_ASG 41
- #define _POW_ASG 42
- #define F_ASSIGN 43
- #define F_ADD_ASG 44
- #define F_SUB_ASG 45
- #define F_MUL_ASG 46
- #define F_DIV_ASG 47
- #define F_MOD_ASG 48
- #define F_POW_ASG 49
- #define _CAT 50
- #define _BUILTIN 51
- #define _PRINT 52
- #define _POST_INC 53
- #define _POST_DEC 54
- #define _PRE_INC 55
- #define _PRE_DEC 56
- #define F_POST_INC 57
- #define F_POST_DEC 58
- #define F_PRE_INC 59
- #define F_PRE_DEC 60
- #define _JMP 61
- #define _JNZ 62
- #define _JZ 63
- #define _EQ 64
- #define _NEQ 65
- #define _LT 66
- #define _LTE 67
- #define _GT 68
- #define _GTE 69
- #define _MATCH 70
- #define _EXIT 71
- #define _EXIT0 72
- #define _NEXT 73
- #define _RANGE 74
- #define _CALL 75
- #define _RET 76
- #define _RET0 77
-
-
- /* next and exit statements */
-
- extern jmp_buf exit_jump, next_jump ;
- extern int exit_code ;
-
- #endif /* CODE_H */
- @//E*O*F mawk0.97/code.h//
- chmod u=rw,g=r,o=r mawk0.97/code.h
-
- echo x - mawk0.97/da.c
- sed 's/^@//' > "mawk0.97/da.c" <<'@//E*O*F mawk0.97/da.c//'
-
- /********************************************
- da.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /* $Log: da.c,v $
- * Revision 2.1 91/04/08 08:22:50 brennan
- * VERSION 0.97
- *
- */
-
-
- /* da.c */
- /* disassemble code */
-
-
- #include "mawk.h"
- #include "code.h"
- #include "bi_funct.h"
- #include "repl.h"
- #include "field.h"
-
- char *PROTO(find_bi_name, (PF_CP) ) ;
-
- void da(start, fp)
- INST *start ;
- FILE *fp ;
- { CELL *cp ;
- register INST *p = start ;
-
- while ( 1 )
- { /* print the relative code address (label) */
- fprintf(fp,"%03d ", p - start) ;
-
- switch( p++->op )
- {
- case _HALT : fprintf(fp,"halt\n") ; return ;
- case _STOP : fprintf(fp,"stop\n") ; break ;
- case _STOP0 : fprintf(fp, "stop0\n") ; break ;
-
- case _PUSHC :
- cp = (CELL *) p++->ptr ;
- switch( cp->type )
- { case C_DOUBLE :
- fprintf(fp,"pushc\t%.6g\n" , cp ->dval) ;
- break ;
-
- case C_STRING :
- fprintf(fp,"pushc\t\"%s\"\n" ,
- ((STRING *)cp->ptr)->str) ;
- break ;
-
- case C_RE :
- fprintf(fp,"pushc\t0x%x\t/%s/\n" , cp->ptr ,
- re_uncompile(cp->ptr) ) ;
- break ;
-
- case C_SPACE :
- fprintf(fp, "pushc\tspace split\n") ;
- break ;
-
- case C_SNULL :
- fprintf(fp, "pushc\tnull split\n") ;
- break ;
- case C_REPL :
- fprintf(fp, "pushc\trepl\t%s\n" ,
- repl_uncompile(cp) ) ;
- break ;
- case C_REPLV :
- fprintf(fp, "pushc\treplv\t%s\n" ,
- repl_uncompile(cp) ) ;
- break ;
-
- default :
- fprintf(fp,"pushc\tWEIRD\n") ; ;
- break ;
- }
- break ;
-
- case _PUSHA :
- fprintf(fp,"pusha\t0x%x\n", p++ -> ptr) ;
- break ;
-
- case _PUSHI :
- if ( (CELL *)p->ptr == field )
- fprintf(fp, "pushi\t$0\n") ;
- else fprintf(fp,"pushi\t0x%x\n", p -> ptr) ;
- p++ ;
- break ;
-
- case L_PUSHA :
- fprintf( fp, "l_pusha\t%d\n", p++->op) ;
- break ;
-
- case L_PUSHI :
- fprintf( fp, "l_pushi\t%d\n", p++->op) ;
- break ;
-
- case LAE_PUSHI :
- fprintf( fp, "lae_pushi\t%d\n", p++->op) ;
- break ;
-
- case LAE_PUSHA :
- fprintf( fp, "lae_pusha\t%d\n", p++->op) ;
- break ;
-
- case LA_PUSHA :
- fprintf( fp, "la_pusha\t%d\n", p++->op) ;
- break ;
-
- case F_PUSHA :
- fprintf(fp,"f_pusha\t$%d\n" , (CELL *) p++->ptr - field ) ;
- break ;
-
- case F_PUSHI :
- fprintf(fp,"f_pushi\t$%d\n" , (CELL *) p++->ptr - field ) ;
- break ;
-
- case FE_PUSHA :
- fprintf(fp,"fe_pusha\n" ) ;
- break ;
-
- case FE_PUSHI :
- fprintf(fp,"fe_pushi\n" ) ;
- break ;
-
- case AE_PUSHA :
- fprintf(fp,"ae_pusha\t0x%x\n" , p++->ptr) ;
- break ;
-
- case AE_PUSHI :
- fprintf(fp,"ae_pushi\t0x%x\n" , p++->ptr) ;
- break ;
-
- case A_PUSHA :
- fprintf(fp,"a_pusha\t0x%x\n" , p++->ptr) ;
- break ;
-
- case A_TEST :
- fprintf(fp,"a_test\n" ) ;
- break ;
-
- case A_DEL :
- fprintf(fp,"a_del\n" ) ;
- break ;
-
- case A_CAT :
- fprintf(fp,"a_cat\t%d\n", p++->op ) ;
- break ;
-
- case _POP :
- fprintf(fp,"pop\n") ;
- break ;
-
- case _ADD :
- fprintf(fp,"add\n") ; break ;
-
- case _SUB :
- fprintf(fp,"sub\n") ; break ;
- case _MUL :
- fprintf(fp,"mul\n") ; break ;
- case _DIV :
- fprintf(fp,"div\n") ; break ;
- case _MOD :
- fprintf(fp,"mod\n") ; break ;
- case _POW :
- fprintf(fp,"pow\n") ; break ;
- case _NOT :
- fprintf(fp,"not\n") ; break ;
- case _UMINUS :
- fprintf(fp,"uminus\n") ; break ;
- case _UPLUS :
- fprintf(fp,"plus\n") ; break ;
- case _DUP :
- fprintf(fp,"dup\n") ; break ;
- case _TEST :
- fprintf(fp,"test\n") ; break ;
-
- case _CAT :
- fprintf(fp,"cat\n") ; break ;
-
- case _ASSIGN :
- fprintf(fp,"assign\n") ; break ;
- case _ADD_ASG :
- fprintf(fp,"add_asg\n") ; break ;
- case _SUB_ASG :
- fprintf(fp,"sub_asg\n") ; break ;
- case _MUL_ASG :
- fprintf(fp,"mul_asg\n") ; break ;
- case _DIV_ASG :
- fprintf(fp,"div_asg\n") ; break ;
- case _MOD_ASG :
- fprintf(fp,"mod_asg\n") ; break ;
- case _POW_ASG :
- fprintf(fp,"pow_asg\n") ; break ;
-
- case F_ASSIGN :
- fprintf(fp,"f_assign\n") ; break ;
- case F_ADD_ASG :
- fprintf(fp,"f_add_asg\n") ; break ;
- case F_SUB_ASG :
- fprintf(fp,"f_sub_asg\n") ; break ;
- case F_MUL_ASG :
- fprintf(fp,"f_mul_asg\n") ; break ;
- case F_DIV_ASG :
- fprintf(fp,"f_div_asg\n") ; break ;
- case F_MOD_ASG :
- fprintf(fp,"f_mod_asg\n") ; break ;
- case F_POW_ASG :
- fprintf(fp,"f_pow_asg\n") ; break ;
-
- case _PUSHINT :
- fprintf(fp,"pushint\t%d\n" , p++ -> op ) ;
- break ;
-
- case _BUILTIN :
- fprintf(fp,"%s\n" ,
- find_bi_name( (PF_CP) p++ -> ptr ) ) ;
- break ;
-
- case _PRINT :
- fprintf(fp,"%s\n",
- (PF_CP) p++ -> ptr == bi_printf
- ? "printf" : "print") ;
- break ;
-
- case _POST_INC :
- fprintf(fp,"post_inc\n") ; break ;
-
- case _POST_DEC :
- fprintf(fp,"post_dec\n") ; break ;
-
- case _PRE_INC :
- fprintf(fp,"pre_inc\n") ; break ;
-
- case _PRE_DEC :
- fprintf(fp,"pre_dec\n") ; break ;
-
- case F_POST_INC :
- fprintf(fp,"f_post_inc\n") ; break ;
-
- case F_POST_DEC :
- fprintf(fp,"f_post_dec\n") ; break ;
-
- case F_PRE_INC :
- fprintf(fp,"f_pre_inc\n") ; break ;
-
- case F_PRE_DEC :
- fprintf(fp,"f_pre_dec\n") ; break ;
-
- case _JMP :
- case _JNZ :
- case _JZ :
- { int j = (p-1)->op ;
- char *s = j == _JMP ? "jmp" :
- j == _JNZ ? "jnz" : "jz" ;
-
- fprintf(fp,"%s\t\t%03d\n" , s ,
- (p - start) + p->op - 1 ) ;
- p++ ;
- break ;
- }
-
- case _EQ :
- fprintf(fp,"eq\n") ; break ;
-
- case _NEQ :
- fprintf(fp,"neq\n") ; break ;
-
- case _LT :
- fprintf(fp,"lt\n") ; break ;
-
- case _LTE :
- fprintf(fp,"lte\n") ; break ;
-
- case _GT :
- fprintf(fp,"gt\n") ; break ;
-
- case _GTE :
- fprintf(fp,"gte\n") ; break ;
-
- case _MATCH :
- fprintf(fp,"match_op\n") ; break ;
-
- case A_LOOP :
- fprintf(fp,"a_loop\t%03d\n", p-start+p[1].op) ;
- p += 2 ;
- break ;
-
- case _EXIT :
- fprintf(fp, "exit\n") ; break ;
-
- case _EXIT0 :
- fprintf(fp, "exit0\n") ; break ;
-
- case _NEXT :
- fprintf(fp, "next\n") ; break ;
-
- case _RET :
- fprintf(fp, "ret\n") ; break ;
- case _RET0 :
- fprintf(fp, "ret0\n") ; break ;
-
- case _CALL :
- fprintf(fp, "call\t%s\t%d\n",
- ((FBLOCK*)p->ptr)->name , p[1].op) ;
- p += 2 ;
- break ;
-
- case _RANGE :
- fprintf(fp, "range\t%03d %03d %03d\n",
- /* label for pat2, action, follow */
- p - start + p[1].op ,
- p - start + p[2].op ,
- p - start + p[3].op ) ;
- p += 4 ;
- break ;
- default :
- fprintf(fp,"bad instruction\n") ;
- return ;
- }
- }
- }
-
- static struct {
- PF_CP action ;
- char *name ;
- } special_cases[] = {
- bi_length, "length",
- bi_split, "split",
- bi_match, "match",
- bi_getline,"getline",
- bi_sub, "sub",
- bi_gsub , "gsub",
- (PF_CP) 0, (char *) 0 } ;
-
- static char *find_bi_name( p )
- PF_CP p ;
- { BI_REC *q ;
- int i ;
-
- for( q = bi_funct ; q->name ; q++ )
- if ( q->fp == p ) /* found */
- return q->name ;
- /* next check some special cases */
- for( i = 0 ; special_cases[i].action ; i++)
- if ( special_cases[i].action == p )
- return special_cases[i].name ;
-
- return "unknown builtin" ;
- }
-
- static struct fdump {
- struct fdump *link ;
- FBLOCK *fbp ;
- } *fdump_list ; /* linked list of all user functions */
-
- void add_to_fdump_list( fbp )
- FBLOCK *fbp ;
- { struct fdump *p = (struct fdump *)zmalloc(sizeof(struct fdump)) ;
- p->fbp = fbp ;
- p->link = fdump_list ; fdump_list = p ;
- }
-
- void fdump()
- {
- register struct fdump *p, *q = fdump_list ;
-
- while ( p = q )
- { q = p->link ;
- fprintf(stderr, "function %s\n" , p->fbp->name) ;
- da(p->fbp->code, stderr) ;
- zfree(p, sizeof(struct fdump)) ;
- }
- }
- @//E*O*F mawk0.97/da.c//
- chmod u=rw,g=r,o=r mawk0.97/da.c
-
- echo x - mawk0.97/error.c
- sed 's/^@//' > "mawk0.97/error.c" <<'@//E*O*F mawk0.97/error.c//'
-
- /********************************************
- error.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /* $Log: error.c,v $
- * Revision 2.2 91/04/09 12:38:52 brennan
- * added static to funct decls to satisfy STARDENT compiler
- *
- * Revision 2.1 91/04/08 08:22:52 brennan
- * VERSION 0.97
- *
- */
-
-
- #include "mawk.h"
- #include "scan.h"
- #include "bi_vars.h"
-
- #ifndef EOF
- #define EOF (-1)
- #endif
-
- /* statics */
- static void PROTO( check_FILENAME, (void) ) ;
- static void PROTO( unexpected_char, (void) ) ;
- static void PROTO( missing, (int, char *, int) ) ;
- static char *PROTO( type_to_str, (int) ) ;
-
-
- static struct token_str {
- short token ;
- char *str ; } token_str[] = {
- EOF , "end of file" ,
- NL , "end of line",
- SEMI_COLON , ";" ,
- LBRACE , "{" ,
- RBRACE , "}" ,
- SC_FAKE_SEMI_COLON, "}",
- LPAREN , "(" ,
- RPAREN , ")" ,
- LBOX , "[",
- RBOX , "]",
- QMARK , "?",
- COLON , ":",
- OR, "||",
- AND, "&&",
- P_OR, "||",
- P_AND, "&&",
- ASSIGN , "=" ,
- ADD_ASG, "+=",
- SUB_ASG, "-=",
- MUL_ASG, "*=",
- DIV_ASG, "/=",
- MOD_ASG, "%=",
- POW_ASG, "^=",
- EQ , "==" ,
- NEQ , "!=",
- LT, "<" ,
- LTE, "<=" ,
- GT, ">",
- GTE, ">=" ,
- MATCH, "~",
- NOT_MATCH, "!~",
- PLUS , "+" ,
- MINUS, "-" ,
- MUL , "*" ,
- DIV, "/" ,
- MOD, "%" ,
- POW, "^" ,
- INC , "++" ,
- DEC , "--" ,
- NOT, "!" ,
- COMMA, "," ,
- CONSTANT , temp_buff.string_buff ,
- ID , temp_buff.string_buff ,
- FUNCT_ID , temp_buff.string_buff ,
- BUILTIN , temp_buff.string_buff ,
- IO_OUT, temp_buff.string_buff,
- IO_IN, "<" ,
- PIPE, "|" ,
- DOLLAR, "$" ,
- FIELD, "$" ,
- 0, (char *) 0 } ;
-
- /* if paren_cnt >0 and we see one of these, we are missing a ')' */
- static int missing_rparen[] =
- { EOF, NL, SEMI_COLON, SC_FAKE_SEMI_COLON, RBRACE, 0 } ;
-
- /* ditto for '}' */
- static int missing_rbrace[] =
- { EOF, BEGIN, END , 0 } ;
-
- static void missing( c, n , ln)
- int c ;
- char *n ;
- int ln ;
- { errmsg(0, "line %u: missing %c near %s" , ln, c, n) ; }
-
- void yyerror(s)
- char *s ; /* we won't use s as input
- (yacc and bison force this).
- We will use s for storage to keep lint or the compiler
- off our back */
- { struct token_str *p ;
- int *ip ;
-
- s = (char *) 0 ;
-
- for ( p = token_str ; p->token ; p++ )
- if ( current_token == p->token )
- { s = p->str ; break ; }
-
- if ( ! s ) /* search the keywords */
- s = find_kw_str(current_token) ;
-
- if ( s )
- {
- if ( paren_cnt )
- for( ip = missing_rparen ; *ip ; ip++)
- if ( *ip == current_token )
- { missing(')', s, token_lineno) ;
- paren_cnt = 0 ;
- goto done ;
- }
-
- if ( brace_cnt )
- for( ip = missing_rbrace ; *ip ; ip++)
- if ( *ip == current_token )
- { missing('}', s, token_lineno) ;
- brace_cnt = 0 ;
- goto done ;
- }
-
- compile_error("syntax error at or near %s", s) ;
-
- }
- else /* special cases */
- switch ( current_token )
- {
- case UNEXPECTED :
- unexpected_char() ;
- goto done ;
-
- case BAD_DECIMAL :
- compile_error(
- "syntax error in decimal constant %s",
- temp_buff.string_buff ) ;
- break ;
-
- case RE :
- compile_error(
- "syntax error at or near /%s/",
- temp_buff.string_buff ) ;
- break ;
-
- default :
- compile_error("syntax error") ;
- break ;
- }
- return ;
-
- done :
- if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
- }
-
- /* system provided errnos and messages */
- extern int sys_nerr ;
- extern char *sys_errlist[] ;
-
- #ifdef __STDC__
- #include <stdarg.h>
-
- /* generic error message with a hook into the system error
- messages if errnum > 0 */
-
- void errmsg(int errnum, char *format, ...)
- { va_list args ;
-
- fprintf(stderr, "%s: " , progname) ;
- va_start(args, format) ;
- (void) vfprintf(stderr, format, args) ;
- va_end(args) ;
- if ( errnum > 0 && errnum < sys_nerr )
- fprintf(stderr, " (%s)" , sys_errlist[errnum]) ;
- fprintf( stderr, "\n") ;
- }
-
- void compile_error(char *format, ...)
- { va_list args ;
-
- fprintf(stderr, "%s: line %u: " , progname, token_lineno) ;
- va_start(args, format) ;
- vfprintf(stderr, format, args) ;
- va_end(args) ;
- fprintf(stderr, "\n") ;
- if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
- }
-
- void rt_error( char *format, ...)
- { va_list args ;
-
- fprintf(stderr, "%s: run time error: " , progname ) ;
- va_start(args, format) ;
- vfprintf(stderr, format, args) ;
- va_end(args) ;
- check_FILENAME() ;
- fprintf(stderr, "\n\t(FILENAME=\"%s\" FNR=%g NR=%g)\n" ,
- string(bi_vars+FILENAME)->str, bi_vars[FNR].dval,
- bi_vars[NR].dval) ;
- mawk_exit(1) ;
- }
-
- #else
-
- #include <varargs.h>
-
- /* void errmsg(errnum, format, ...) */
-
- void errmsg( va_alist)
- va_dcl
- { va_list ap ;
- int errnum ;
- char *format ;
-
- fprintf(stderr, "%s: " , progname) ;
- va_start(ap) ;
- errnum = va_arg(ap, int) ;
- format = va_arg(ap, char *) ;
- (void) vfprintf(stderr, format, ap) ;
- if ( errnum > 0 && errnum < sys_nerr )
- fprintf(stderr, " (%s)" , sys_errlist[errnum]) ;
- fprintf( stderr, "\n") ;
- }
-
- void compile_error( va_alist )
- va_dcl
- { va_list args ;
- char *format ;
-
- fprintf(stderr, "%s: line %u: " , progname, token_lineno) ;
- va_start(args) ;
- format = va_arg(args, char *) ;
- vfprintf(stderr, format, args) ;
- va_end(args) ;
- fprintf(stderr, "\n") ;
- if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
- }
-
- void rt_error( va_alist )
- va_dcl
- { va_list args ;
- char *format ;
-
- fprintf(stderr, "%s: run time error: " , progname ) ;
- va_start(args) ;
- format = va_arg(args, char *) ;
- vfprintf(stderr, format, args) ;
- va_end(args) ;
- check_FILENAME() ;
- fprintf(stderr, "\n\tFILENAME=\"%s\" FNR=%g NR=%g\n" ,
- string(bi_vars+FILENAME)->str, bi_vars[FNR].dval,
- bi_vars[NR].dval) ;
- mawk_exit(1) ;
- }
-
- #endif
-
- void bozo(s)
- char *s ;
- { errmsg(0, "bozo: %s" , s) ; mawk_exit(1) ; }
-
- void overflow(s, size)
- char *s ; unsigned size ;
- { errmsg(0 , "program limit exceeded: %s size=%u", s, size) ;
- mawk_exit(1) ; }
-
- static void check_FILENAME()
- {
- if ( bi_vars[FILENAME].type != C_STRING )
- cast1_to_s(bi_vars + FILENAME) ;
- if ( bi_vars[FNR].type != C_DOUBLE )
- cast1_to_d(bi_vars + FNR ) ;
- if ( bi_vars[NR].type != C_DOUBLE )
- cast1_to_d(bi_vars + NR ) ;
- }
-
- /* run time */
- void rt_overflow(s, size)
- char *s ; unsigned size ;
- { check_FILENAME() ;
- errmsg(0 ,
- "program limit exceeded: %s size=%u\n\
- \t(FILENAME=\"%s\" FNR=%g NR=%g)",
- s, size, string(bi_vars+FILENAME)->str,
- bi_vars[FNR].dval,
- bi_vars[NR].dval) ;
- mawk_exit(1) ;
- }
-
- static void unexpected_char()
- { int c = yylval.ival ;
-
- fprintf(stderr, "%s: %u: ", progname, token_lineno) ;
- if ( c > ' ')
- fprintf(stderr, "unexpected character '%c'\n" , c) ;
- else
- fprintf(stderr, "unexpected character 0x%02x\n" , c) ;
- }
-
- static char *type_to_str( type )
- int type ;
- { char *retval ;
-
- switch( type )
- {
- case ST_VAR : retval = "variable" ; break ;
- case ST_ARRAY : retval = "array" ; break ;
- case ST_FUNCT : retval = "function" ; break ;
- case ST_LOCAL_VAR : retval = "local variable" ; break ;
- case ST_LOCAL_ARRAY : retval = "local array" ; break ;
- default : bozo("type_to_str") ;
- }
- return retval ;
- }
-
- /* emit an error message about a type clash */
- void type_error(p)
- SYMTAB *p ;
- { compile_error("illegal reference to %s %s",
- type_to_str(p->type) , p->name) ;
- }
-
-
- @//E*O*F mawk0.97/error.c//
- chmod u=rw,g=r,o=r mawk0.97/error.c
-
- echo x - mawk0.97/execute.c
- sed 's/^@//' > "mawk0.97/execute.c" <<'@//E*O*F mawk0.97/execute.c//'
-
- /********************************************
- execute.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /* $Log: execute.c,v $
- * Revision 2.2 91/04/09 12:38:54 brennan
- * added static to funct decls to satisfy STARDENT compiler
- *
- * Revision 2.1 91/04/08 08:22:55 brennan
- * VERSION 0.97
- *
- */
-
-
- #include "mawk.h"
- #include "code.h"
- #include "memory.h"
- #include "symtype.h"
- #include "field.h"
- #include "bi_funct.h"
- #include "regexp.h"
- #include "repl.h"
- #include <math.h>
-
- /* static functions */
- static int PROTO( compare, (CELL *) ) ;
- static void PROTO( eval_overflow, (void) ) ;
-
- #ifdef DEBUG
- #define inc_sp() if( ++sp == eval_stack+EVAL_STACK_SIZE )\
- eval_overflow()
- #else
-
- /* If things are working, the only reason the eval stack should
- overflow is too much function recursion
- (checked for at _CALL below */
-
- #define inc_sp() sp++
- #endif
-
- #define SAFETY 3 /* if we get within 3 of stack top emit
- overflow */
-
- /* The stack machine that executes the code */
-
- CELL eval_stack[EVAL_STACK_SIZE] ;
-
- static void eval_overflow()
- { overflow("eval stack" , EVAL_STACK_SIZE) ; mawk_exit(1) ; }
-
- /* if this flag is on, recursive calls to execute need to
- return to the _CALL statement. This only happens
- inside array loops */
- int returning ;
-
- INST *execute(cdp, sp, fp)
- register INST *cdp ; /* code ptr, start execution here */
- register CELL *sp ; /* eval_stack pointer */
- CELL *fp ; /* frame ptr into eval_stack for
- user defined functions */
- {
- /* some useful temporaries */
- CELL *cp , tc ;
- int t ;
-
- #ifdef DEBUG
- CELL *entry_sp = sp ;
- #endif
-
- while ( 1 )
- switch( cdp++ -> op )
- { case _HALT :
- case _STOP :
-
- #ifdef DEBUG
- /* check the stack is sane */
- if ( sp != entry_sp ) bozo("stop") ;
- return cdp - 1 ;
-
- case _STOP0 : /* if debugging stops range patterns */
- if ( sp != entry_sp+1 ) bozo("stop0") ;
- #else
- case _STOP0 :
- #endif
- return cdp - 1 ;
-
- case _PUSHC :
- inc_sp() ;
- (void) cellcpy(sp, cdp++ -> ptr) ;
- break ;
-
- case F_PUSHA :
- if ( (CELL*)cdp->ptr != field && nf < 0 ) split_field0() ;
- /* fall thru */
-
- case _PUSHA :
- case A_PUSHA :
- inc_sp() ;
- sp -> ptr = cdp++ -> ptr ;
- break ;
-
- case _PUSHI : /* put contents of next address on stack*/
- inc_sp() ;
- (void) cellcpy(sp, cdp++ -> ptr) ;
- break ;
-
- case L_PUSHI :
- /* put the contents of a local var on stack,
- cdp->op holds the offset from the frame pointer */
- inc_sp() ;
- (void) cellcpy(sp, fp + cdp++->op) ;
- break ;
-
- case L_PUSHA : /* put a local address on eval stack */
- inc_sp() ;
- sp->ptr = (PTR)(fp + cdp++->op) ;
- break ;
-
-
- case F_PUSHI :
-
- /* note $0 , RS , FS and OFMT are loaded by _PUSHI */
-
- inc_sp() ;
- if ( nf < 0 ) split_field0() ;
- if ( (t = (CELL *) cdp->ptr - field) <= nf ||
- t == NF )
- { (void) cellcpy(sp, cdp++ -> ptr) ; }
- else /* an unset field */
- { sp->type = C_STRING ;
- sp->ptr = (PTR) & null_str ;
- null_str.ref_cnt++ ;
- cdp++ ;
- }
- break ;
-
- case FE_PUSHA :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- if ( (t = (int) sp->dval) < 0 )
- rt_error( "negative field index(%d)", t) ;
- if ( t > MAX_FIELD )
- rt_overflow("MAX_FIELD", MAX_FIELD) ;
- if ( t && nf < 0 ) split_field0() ;
- sp->ptr = (PTR) &field[t] ;
- break ;
-
- case FE_PUSHI :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
-
- if ( (t = (int) sp->dval) == 0 )
- { (void) cellcpy(sp, &field[0]) ; break ; }
-
- if ( t < 0 )
- rt_error( "negative field index(%d)", t) ;
- if ( t > MAX_FIELD )
- rt_overflow("MAX_FIELD", MAX_FIELD) ;
-
- if ( nf < 0) split_field0() ;
- if ( t <= nf ) (void) cellcpy(sp, &field[t]) ;
- else
- { sp->type = C_STRING ;
- sp->ptr = (PTR) & null_str ;
- null_str.ref_cnt++ ;
- }
- break ;
-
-
- case AE_PUSHA :
- /* top of stack has an expr, cdp->ptr points at an
- array, replace the expr with the cell address inside
- the array */
- cast1_to_s(sp) ;
- cp = array_find((ARRAY)cdp++->ptr, sp->ptr, 0) ;
- free_STRING( string(sp) );
- sp->ptr = (PTR) cp ;
- break ;
-
- case AE_PUSHI :
- /* top of stack has an expr, cdp->ptr points at an
- array, replace the expr with the contents of the
- cell inside the array */
- cast1_to_s(sp) ;
- cp = array_find((ARRAY) cdp++->ptr, sp->ptr, 0) ;
- free_STRING(string(sp)) ;
- (void) cellcpy(sp, cp) ;
- break ;
-
- case LAE_PUSHI :
- /* sp[0] is an expression
- cdp->op is offset from frame pointer of a CELL which
- has an ARRAY in the ptr field, replace expr
- with array[expr]
- */
- cast1_to_s(sp) ;
- cp = array_find( (ARRAY)fp[cdp++->op].ptr, sp->ptr, 0) ;
- free_STRING(string(sp)) ;
- (void) cellcpy(sp, cp) ;
- break ;
-
- case LAE_PUSHA :
- /* sp[0] is an expression
- cdp->op is offset from frame pointer of a CELL which
- has an ARRAY in the ptr field, replace expr
- with & array[expr]
- */
- cast1_to_s(sp) ;
- cp = array_find( (ARRAY)fp[cdp++->op].ptr, sp->ptr, 0) ;
- free_STRING(string(sp)) ;
- sp->ptr = (PTR) cp ;
- break ;
-
- case LA_PUSHA :
- /* cdp->op is offset from frame pointer of a CELL which
- has an ARRAY in the ptr field. Push this ARRAY
- on the eval stack
- */
- inc_sp() ;
- sp->ptr = fp[cdp++->op].ptr ;
- break ;
-
- case A_LOOP :
- cdp = array_loop(cdp,sp,fp) ;
- if ( returning ) return cdp ; /*value doesn't matter*/
- sp -= 2 ;
- break ;
-
- case _POP :
- cell_destroy(sp) ;
- sp-- ;
- break ;
-
- case _DUP :
- (void) cellcpy(sp+1, sp) ;
- sp++ ; break ;
-
- case _ASSIGN :
- /* top of stack has an expr, next down is an
- address, put the expression in *address and
- replace the address with the expression */
-
- /* don't propagate type C_MBSTRN */
- if ( sp->type == C_MBSTRN ) check_strnum(sp) ;
- sp-- ;
- cell_destroy( ((CELL *)sp->ptr) ) ;
- (void) cellcpy( sp, cellcpy(sp->ptr, sp+1) ) ;
- cell_destroy(sp+1) ;
- break ;
-
- case F_ASSIGN : /* assign to a field */
- if (sp->type == C_MBSTRN) check_strnum(sp) ;
- sp-- ;
- field_assign((CELL*)sp->ptr - field, sp+1) ;
- cell_destroy(sp+1) ;
- (void) cellcpy(sp, (CELL *) sp->ptr) ;
- break ;
-
- case _ADD_ASG:
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- cp->dval += sp-- -> dval ;
- sp->type = C_DOUBLE ;
- sp->dval = cp->dval ;
- break ;
-
- case _SUB_ASG:
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- cp->dval -= sp-- -> dval ;
- sp->type = C_DOUBLE ;
- sp->dval = cp->dval ;
- break ;
-
- case _MUL_ASG:
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- cp->dval *= sp-- -> dval ;
- sp->type = C_DOUBLE ;
- sp->dval = cp->dval ;
- break ;
-
- case _DIV_ASG:
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- cp->dval /= sp-- -> dval ;
- sp->type = C_DOUBLE ;
- sp->dval = cp->dval ;
- break ;
-
- case _MOD_ASG:
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- cp->dval = fmod(cp->dval,sp-- -> dval) ;
- sp->type = C_DOUBLE ;
- sp->dval = cp->dval ;
- break ;
-
- case _POW_ASG:
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- cp->dval = pow(cp->dval,sp-- -> dval) ;
- sp->type = C_DOUBLE ;
- sp->dval = cp->dval ;
- break ;
-
- /* will anyone ever use these ? */
-
- case F_ADD_ASG :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- cast1_to_d( cellcpy(&tc, cp) ) ;
- tc.dval += sp-- -> dval ;
- sp->type = C_DOUBLE ;
- sp->dval = tc.dval ;
- field_assign(cp-field, &tc) ;
- break ;
-
- case F_SUB_ASG :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- cast1_to_d( cellcpy(&tc, cp) ) ;
- tc.dval -= sp-- -> dval ;
- sp->type = C_DOUBLE ;
- sp->dval = tc.dval ;
- field_assign(cp-field, &tc) ;
- break ;
-
- case F_MUL_ASG :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- cast1_to_d( cellcpy(&tc, cp) ) ;
- tc.dval *= sp-- -> dval ;
- sp->type = C_DOUBLE ;
- sp->dval = tc.dval ;
- field_assign(cp-field, &tc) ;
- break ;
-
- case F_DIV_ASG :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- cast1_to_d( cellcpy(&tc, cp) ) ;
- tc.dval /= sp-- -> dval ;
- sp->type = C_DOUBLE ;
- sp->dval = tc.dval ;
- field_assign(cp-field, &tc) ;
- break ;
-
- case F_MOD_ASG :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- cast1_to_d( cellcpy(&tc, cp) ) ;
- tc.dval = fmod(tc.dval, sp-- -> dval) ;
- sp->type = C_DOUBLE ;
- sp->dval = tc.dval ;
- field_assign(cp-field, &tc) ;
- break ;
-
- case F_POW_ASG :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- cp = (CELL *) (sp-1)->ptr ;
- cast1_to_d( cellcpy(&tc, cp) ) ;
- tc.dval = pow(tc.dval, sp-- -> dval) ;
- sp->type = C_DOUBLE ;
- sp->dval = tc.dval ;
- field_assign(cp-field, &tc) ;
- break ;
-
- case _ADD :
- sp-- ;
- if ( TEST2(sp) != TWO_DOUBLES )
- cast2_to_d(sp) ;
- sp[0].dval += sp[1].dval ;
- break ;
-
- case _SUB :
- sp-- ;
- if ( TEST2(sp) != TWO_DOUBLES )
- cast2_to_d(sp) ;
- sp[0].dval -= sp[1].dval ;
- break ;
-
- case _MUL :
- sp-- ;
- if ( TEST2(sp) != TWO_DOUBLES )
- cast2_to_d(sp) ;
- sp[0].dval *= sp[1].dval ;
- break ;
-
- case _DIV :
- sp-- ;
- if ( TEST2(sp) != TWO_DOUBLES )
- cast2_to_d(sp) ;
- sp[0].dval /= sp[1].dval ;
- break ;
-
- case _MOD :
- sp-- ;
- if ( TEST2(sp) != TWO_DOUBLES )
- cast2_to_d(sp) ;
- sp[0].dval = fmod(sp[0].dval,sp[1].dval) ;
- break ;
-
- case _POW :
- sp-- ;
- if ( TEST2(sp) != TWO_DOUBLES )
- cast2_to_d(sp) ;
- sp[0].dval = pow(sp[0].dval,sp[1].dval) ;
- break ;
-
- case _NOT :
- reswitch_1:
- switch( sp->type )
- { case C_NOINIT :
- sp->dval = 1.0 ; break ;
- case C_DOUBLE :
- sp->dval = sp->dval ? 0.0 : 1.0 ;
- break ;
- case C_STRING :
- sp->dval = string(sp)->len ? 0.0 : 1.0 ;
- free_STRING(string(sp)) ;
- break ;
- case C_STRNUM : /* test as a number */
- sp->dval = sp->dval ? 0.0 : 1.0 ;
- free_STRING(string(sp)) ;
- break ;
- case C_MBSTRN :
- check_strnum(sp) ;
- goto reswitch_1 ;
- default :
- bozo("bad type on eval stack") ;
- }
- sp->type = C_DOUBLE ;
- break ;
-
- case _TEST :
- reswitch_2:
- switch( sp->type )
- { case C_NOINIT :
- sp->dval = 0.0 ; break ;
- case C_DOUBLE :
- sp->dval = sp->dval ? 1.0 : 0.0 ;
- break ;
- case C_STRING :
- sp->dval = string(sp)->len ? 1.0 : 0.0 ;
- free_STRING(string(sp)) ;
- break ;
- case C_STRNUM : /* test as a number */
- sp->dval = sp->dval ? 0.0 : 1.0 ;
- free_STRING(string(sp)) ;
- break ;
- case C_MBSTRN :
- check_strnum(sp) ;
- goto reswitch_2 ;
- default :
- bozo("bad type on eval stack") ;
- }
- sp->type = C_DOUBLE ;
- break ;
-
- case _UMINUS :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- sp->dval = - sp->dval ;
- break ;
-
- case _UPLUS :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- break ;
-
- case _CAT :
- { unsigned len1, len2 ;
- char *str1, *str2 ;
- STRING *b ;
-
- sp-- ;
- if ( TEST2(sp) != TWO_STRINGS )
- cast2_to_s(sp) ;
- str1 = string(sp)->str ;
- len1 = string(sp)->len ;
- str2 = string(sp+1)->str ;
- len2 = string(sp+1)->len ;
-
- b = new_STRING((char *)0, len1+len2) ;
- (void) memcpy(b->str, str1, len1) ;
- (void) memcpy(b->str + len1, str2, len2) ;
- free_STRING(string(sp)) ;
- free_STRING( string(sp+1) ) ;
-
- sp->ptr = (PTR) b ;
- break ;
- }
-
- case _PUSHINT :
- inc_sp() ;
- sp->type = cdp++ -> op ;
- break ;
-
- case _BUILTIN :
- case _PRINT :
- sp = (* (PF_CP) cdp++ -> ptr) (sp) ;
- break ;
-
- case _POST_INC :
- (void) cellcpy(sp, cp = (CELL *)sp->ptr) ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- cp->dval += 1.0 ;
- break ;
-
- case _POST_DEC :
- (void) cellcpy(sp, cp = (CELL *)sp->ptr) ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- cp->dval -= 1.0 ;
- break ;
-
- case _PRE_INC :
- cp = (CELL *) sp->ptr ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- sp->dval = cp->dval += 1.0 ;
- sp->type = C_DOUBLE ;
- break ;
-
- case _PRE_DEC :
- cp = (CELL *) sp->ptr ;
- if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
- sp->dval = cp->dval -= 1.0 ;
- sp->type = C_DOUBLE ;
- break ;
-
-
- case F_POST_INC :
- cp = (CELL *) sp->ptr ;
- (void) cellcpy(sp, cellcpy(&tc, cp) ) ;
- cast1_to_d(&tc) ;
- tc.dval += 1.0 ;
- field_assign(cp-field, &tc) ;
- break ;
-
- case F_POST_DEC :
- cp = (CELL *) sp->ptr ;
- (void) cellcpy(sp, cellcpy(&tc, cp) ) ;
- cast1_to_d(&tc) ;
- tc.dval -= 1.0 ;
- field_assign(cp-field, &tc) ;
- break ;
-
- case F_PRE_INC :
- cp = (CELL *) sp->ptr ;
- cast1_to_d(cellcpy(&tc, cp)) ;
- sp->dval = tc.dval += 1.0 ;
- sp->type = C_DOUBLE ;
- field_assign(cp-field, sp) ;
- break ;
-
- case F_PRE_DEC :
- cp = (CELL *) sp->ptr ;
- cast1_to_d(cellcpy(&tc, cp)) ;
- sp->dval = tc.dval -= 1.0 ;
- sp->type = C_DOUBLE ;
- field_assign(cp-field, sp) ;
- break ;
-
- case _JMP :
- cdp += cdp->op - 1 ;
- break ;
-
- case _JNZ :
- /* jmp if top of stack is non-zero and pop stack */
- if ( test( sp ) )
- cdp += cdp->op - 1 ;
- else cdp++ ;
- cell_destroy(sp) ;
- sp-- ;
- break ;
-
- case _JZ :
- /* jmp if top of stack is zero and pop stack */
- if ( ! test( sp ) )
- cdp += cdp->op - 1 ;
- else cdp++ ;
- cell_destroy(sp) ;
- sp-- ;
- break ;
-
- /* the relation operations */
- /* compare() makes sure string ref counts are OK */
- case _EQ :
- t = compare(--sp) ;
- sp->type = C_DOUBLE ;
- sp->dval = t == 0 ? 1.0 : 0.0 ;
- break ;
-
- case _NEQ :
- t = compare(--sp) ;
- sp->type = C_DOUBLE ;
- sp->dval = t ? 1.0 : 0.0 ;
- break ;
-
- case _LT :
- t = compare(--sp) ;
- sp->type = C_DOUBLE ;
- sp->dval = t < 0 ? 1.0 : 0.0 ;
- break ;
-
- case _LTE :
- t = compare(--sp) ;
- sp->type = C_DOUBLE ;
- sp->dval = t <= 0 ? 1.0 : 0.0 ;
- break ;
-
- case _GT :
- t = compare(--sp) ;
- sp->type = C_DOUBLE ;
- sp->dval = t > 0 ? 1.0 : 0.0 ;
- break ;
-
- case _GTE :
- t = compare(--sp) ;
- sp->type = C_DOUBLE ;
- sp->dval = t >= 0 ? 1.0 : 0.0 ;
- break ;
-
- case _MATCH :
- /* does sp[-1] match sp[0] as re */
- if ( sp->type != C_RE ) cast_to_RE(sp) ;
-
- if ( (--sp)->type < C_STRING ) cast1_to_s(sp) ;
- t = REtest(string(sp)->str, (sp+1)->ptr) ;
-
- free_STRING(string(sp)) ;
- sp->type = C_DOUBLE ;
- sp->dval = t ? 1.0 : 0.0 ;
- break ;
-
- case A_TEST :
- /* entry : sp[0].ptr-> an array
- sp[-1] is an expression
-
- we compute expression in array */
- if ( (--sp)->type < C_STRING ) cast1_to_s(sp) ;
- t = array_test( (sp+1)->ptr, string(sp)) ;
- free_STRING(string(sp)) ;
- sp->type = C_DOUBLE ;
- sp->dval = t ? 1.0 : 0.0 ;
- break ;
-
- case A_DEL :
- /* sp[0].ptr -> array)
- sp[-1] is an expr
- delete array[expr] */
-
- cast1_to_s(--sp) ;
- array_delete( sp[1].ptr , sp->ptr) ;
- free_STRING( string(sp) ) ;
- sp-- ;
- break ;
-
- /* form a multiple array index */
- case A_CAT :
- sp = array_cat(sp, cdp++->op) ;
- break ;
-
- case _EXIT0 :
- longjmp( exit_jump, 1) ;
-
- case _EXIT :
- if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
- exit_code = (int) sp->dval ;
- longjmp( exit_jump, 1) ;
-
- case _NEXT :
- longjmp(next_jump, 1) ;
-
- case _RANGE :
- /* test a range pattern: pat1, pat2 { action }
- entry :
- cdp[0].op -- a flag, test pat1 if on else pat2
- cdp[1].op -- offset of pat2 code from cdp
- cdp[2].op -- offset of action code from cdp
- cdp[3].op -- offset of code after the action from cdp
- cdp[4] -- start of pat1 code
- */
-
- #define FLAG cdp[0].op
- #define PAT2 cdp[1].op
- #define ACTION cdp[2].op
- #define FOLLOW cdp[3].op
- #define PAT1 4
-
- if ( FLAG ) /* test again pat1 */
- {
- (void) execute(cdp + PAT1,sp, fp) ;
- t = test(sp+1) ;
- cell_destroy(sp+1) ;
- if ( t ) FLAG = 0 ;
- else
- { cdp += FOLLOW ;
- break ; /* break the switch */
- }
- }
-
- /* test against pat2 and then perform the action */
- (void) execute(cdp + PAT2, sp, fp) ;
- FLAG = test(sp+1) ;
- cell_destroy(sp+1) ;
- cdp += ACTION ;
- break ;
-
- /* function calls */
-
- case _RET0 :
- inc_sp() ;
- sp->type = C_NOINIT ;
- /* fall thru */
-
- case _RET :
-
- #ifdef DEBUG
- if ( sp != entry_sp+1 ) bozo("ret") ;
- #endif
- returning = 1 ;
- return cdp-1 ;
-
- case _CALL :
-
- { FBLOCK *fbp = (FBLOCK*) cdp++->ptr ;
- int a_args = cdp++->op ; /* actual number of args */
- CELL *nfp = sp - a_args + 1 ; /* new fp for callee */
- CELL *local_p = sp+1; /* first local argument on stack */
- char *type_p ; /* pts to type of an argument */
-
- if ( fbp->nargs ) type_p = fbp->typev + a_args ;
-
- /* create space for locals */
- if ( t = fbp->nargs - a_args ) /* have local args */
- {
- if ( sp + t >= eval_stack + EVAL_STACK_SIZE - SAFETY )
- eval_overflow() ;
-
- while ( t-- )
- { (++sp)->type = C_NOINIT ;
- if ( *type_p++ == ST_LOCAL_ARRAY )
- sp->ptr = (PTR) new_ARRAY() ;
- }
- }
- type_p-- ; /* *type_p is type of last arg */
-
- (void) execute(fbp->code, sp, nfp) ;
- #ifdef DEBUG
- if ( !returning ) bozo("call") ;
- #endif
- returning = 0 ;
-
- /* cleanup the callee's arguments */
- if ( sp >= nfp )
- {
- cp = sp+1 ; /* cp -> the function return */
-
- do
- {
- if ( *type_p-- == ST_LOCAL_ARRAY )
- { if ( sp >= local_p ) array_free(sp->ptr) ; }
- else cell_destroy(sp) ;
-
- } while ( --sp >= nfp ) ;
-
- (void) cellcpy(++sp, cp) ;
- cell_destroy(cp) ;
- }
- else sp++ ; /* no arguments passed */
- }
- break ;
-
- default :
- bozo("bad opcode") ;
- }
- }
-
- int test( cp ) /* test if a cell is null or not */
- register CELL *cp ;
- {
- reswitch :
-
- switch ( cp->type )
- {
- case C_NOINIT : return 0 ;
- case C_STRNUM : /* test as a number */
- case C_DOUBLE : return cp->dval != 0.0 ;
- case C_STRING : return string(cp)->len ;
- case C_MBSTRN : check_strnum(cp) ; goto reswitch ;
-
- default :
- bozo("bad cell type in call to test") ;
- }
- }
-
- /* compare cells at cp and cp+1 and
- frees STRINGs at those cells
- */
-
- static int compare(cp)
- register CELL *cp ;
- { int k ;
-
- reswitch :
-
- switch( TEST2(cp) )
- { case TWO_NOINITS : return 0 ;
-
- case TWO_DOUBLES :
- two_d:
- return cp->dval > (cp+1)->dval ? 1 :
- cp->dval < (cp+1)->dval ? -1 : 0 ;
-
- case TWO_STRINGS :
- case STRING_AND_STRNUM :
- two_s:
- k = strcmp(string(cp)->str, string(cp+1)->str) ;
- free_STRING( string(cp) ) ;
- free_STRING( string(cp+1) ) ;
- return k ;
-
- case NOINIT_AND_DOUBLE :
- case NOINIT_AND_STRNUM :
- case DOUBLE_AND_STRNUM :
- case TWO_STRNUMS :
- cast2_to_d(cp) ; goto two_d ;
-
- case NOINIT_AND_STRING :
- case DOUBLE_AND_STRING :
- cast2_to_s(cp) ; goto two_s ;
-
- case TWO_MBSTRNS :
- check_strnum(cp) ; check_strnum(cp+1) ;
- goto reswitch ;
-
- case NOINIT_AND_MBSTRN :
- case DOUBLE_AND_MBSTRN :
- case STRING_AND_MBSTRN :
- case STRNUM_AND_MBSTRN :
- check_strnum( cp->type == C_MBSTRN ? cp : cp+1 ) ;
- goto reswitch ;
-
- default : /* there are no default cases */
- bozo("bad cell type passed to compare") ;
- }
- }
-
- /* does not assume target was a cell, if so
- then caller should have made a previous
- call to cell_destroy */
-
- CELL *cellcpy(target, source)
- register CELL *target, *source ;
- { switch( target->type = source->type )
- { case C_NOINIT :
- case C_SPACE :
- case C_SNULL :
- break ;
-
- case C_DOUBLE :
- target->dval = source->dval ;
- break ;
-
- case C_STRNUM :
- target->dval = source->dval ;
- /* fall thru */
-
- case C_REPL :
- case C_MBSTRN :
- case C_STRING :
- string(source)->ref_cnt++ ;
- /* fall thru */
-
- case C_RE :
- target->ptr = source->ptr ;
- break ;
-
- case C_REPLV :
- (void) replv_cpy(target, source) ;
- break ;
-
- default :
- bozo("bad cell passed to cellcpy()") ;
- break ;
- }
- return target ;
- }
-
- #ifdef DEBUG
-
- void DB_cell_destroy(cp) /* HANGOVER time */
- register CELL *cp ;
- {
- switch( cp->type )
- { case C_NOINIT :
- case C_DOUBLE : break ;
-
- case C_MBSTRN :
- case C_STRING :
- case C_STRNUM :
- if ( -- string(cp)->ref_cnt == 0 )
- zfree(string(cp) , string(cp)->len+5) ;
- break ;
-
- case C_RE :
- bozo("cell destroy called on RE cell") ;
- default :
- bozo("cell destroy called on bad cell type") ;
- }
- }
-
- #endif
- @//E*O*F mawk0.97/execute.c//
- chmod u=rw,g=r,o=r mawk0.97/execute.c
-
- echo x - mawk0.97/fcall.c
- sed 's/^@//' > "mawk0.97/fcall.c" <<'@//E*O*F mawk0.97/fcall.c//'
-
- /********************************************
- fcall.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /*$Log: fcall.c,v $
- * Revision 2.1 91/04/08 08:22:59 brennan
- * VERSION 0.97
- *
- */
-
- #include "mawk.h"
- #include "symtype.h"
- #include "code.h"
-
- /* This file has functions involved with type checking of
- function calls
- */
-
- static FCALL_REC *PROTO(first_pass, (FCALL_REC *) ) ;
- static CA_REC *PROTO(call_arg_check, (FBLOCK *, CA_REC *,
- INST *, unsigned) ) ;
- static int PROTO(arg_cnt_ok, (FBLOCK *,CA_REC *, unsigned) ) ;
-
-
- static int check_progress ;
- /* flag that indicates call_arg_check() was able to type
- check some call arguments */
-
- /* type checks a list of call arguments,
- returns a list of arguments whose type is still unknown
- */
- static CA_REC *call_arg_check( callee, entry_list , start, line_no)
- FBLOCK *callee ;
- CA_REC *entry_list ;
- INST *start ; /* to locate patch */
- unsigned line_no ; /* for error messages */
- { register CA_REC *q ;
- CA_REC *exit_list = (CA_REC *) 0 ;
-
- check_progress = 0 ;
-
- /* loop :
- take q off entry_list
- test it
- if OK zfree(q) else put on exit_list
- */
-
- while ( q = entry_list )
- {
- entry_list = q->link ;
-
- if ( q->type == ST_NONE )
- { /* try to infer the type */
- /* it might now be in symbol table */
- if ( q->sym_p->type == ST_VAR )
- { /* set type and patch */
- q->type = CA_EXPR ;
- start[q->call_offset+1].ptr = (PTR) q->sym_p->stval.cp ;
- }
- else
- if ( q->sym_p->type == ST_ARRAY )
- { q->type = CA_ARRAY ;
- start[q->call_offset].op = A_PUSHA ;
- start[q->call_offset+1].ptr = (PTR) q->sym_p->stval.array ;
- }
- else /* try to infer from callee */
- {
- switch( callee->typev[q->arg_num] )
- {
- case ST_LOCAL_VAR :
- q->type = CA_EXPR ;
- q->sym_p->type = ST_VAR ;
- q->sym_p->stval.cp = new_CELL() ;
- q->sym_p->stval.cp->type = C_NOINIT ;
- start[q->call_offset+1].ptr =
- (PTR) q->sym_p->stval.cp ;
- break ;
-
- case ST_LOCAL_ARRAY :
- q->type = CA_ARRAY ;
- q->sym_p->type = ST_ARRAY ;
- q->sym_p->stval.array = new_ARRAY() ;
- start[q->call_offset].op = A_PUSHA ;
- start[q->call_offset+1].ptr =
- (PTR) q->sym_p->stval.array ;
- break ;
- }
- }
- }
- else
- if ( q->type == ST_LOCAL_NONE )
- { /* try to infer the type */
- if ( * q->type_p == ST_LOCAL_VAR )
- { /* set type , don't need to patch */
- q->type = CA_EXPR ;
- }
- else
- if ( * q->type_p == ST_LOCAL_ARRAY )
- { q->type = CA_ARRAY ;
- start[q->call_offset].op = LA_PUSHA ;
- /* offset+1 op is OK */
- }
- else /* try to infer from callee */
- {
- switch( callee->typev[q->arg_num] )
- {
- case ST_LOCAL_VAR :
- q->type = CA_EXPR ;
- * q->type_p = ST_LOCAL_VAR ;
- /* do not need to patch */
- break ;
-
- case ST_LOCAL_ARRAY :
- q->type = CA_ARRAY ;
- * q->type_p = ST_LOCAL_ARRAY ;
- start[q->call_offset].op = LA_PUSHA ;
- break ;
- }
- }
- }
-
- /* if we still do not know the type put on the new list
- else type check */
-
- if ( q->type == ST_NONE || q->type == ST_LOCAL_NONE )
- {
- q->link = exit_list ;
- exit_list = q ;
- }
- else /* type known */
- {
- if ( callee->typev[q->arg_num] == ST_LOCAL_NONE )
- callee->typev[q->arg_num] = q->type ;
-
- else
- if ( q->type != callee->typev[q->arg_num] )
- {
- errmsg(0, "line %u: type error in arg(%d) in call to %s",
- line_no, q->arg_num+1, callee->name) ;
- if ( ++compile_error_count == MAX_COMPILE_ERRORS )
- mawk_exit(1) ;
- }
-
- zfree(q, sizeof(CA_REC)) ;
- check_progress = 1 ;
- }
- } /* while */
-
- return exit_list ;
- }
-
-
- static int arg_cnt_ok( fbp, q, line_no )
- FBLOCK *fbp ;
- CA_REC *q ;
- unsigned line_no ;
- {
- if ( q->arg_num >= fbp->nargs )
- {
- errmsg(0, "line %u: too many arguments in call to %s" ,
- line_no, fbp->name ) ;
- if ( ++compile_error_count == MAX_COMPILE_ERRORS )
- mawk_exit(1) ;
-
- return 0 ;
- }
- else return 1 ;
- }
-
-
- FCALL_REC *resolve_list ;
- /* function calls whose arg types need checking
- are stored on this list */
-
-
- /* on first pass thru the resolve list
- we check :
- if forward referenced functions were really defined
- if right number of arguments
- and compute call_start which is now known
- */
-
- static FCALL_REC *first_pass( p )
- register FCALL_REC *p ;
- { FCALL_REC dummy ;
-