4 * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
6 * Absolutely no warranty. Use this software with your own risk.
8 * Permission to use, copy, modify and distribute this software for any
9 * purpose and without fee is hereby granted, provided that the above
10 * copyright and disclaimer notice.
12 * This program was written to fit into 64K+64K memory of the Minix 1.2.
29 extern int getlineflg
;
31 extern SYMBOL
*hashtab
[], *funtab
[];
35 char *emalloc(), *strsave();
36 NODE
*node0(), *node1(), *node2(), *node3(), *node4();
37 NODE
*stat(), *pastat();
38 NODE
*expr(), *expr1(), *expr2(), *expr3(), *expr4();
39 NODE
*expr5(), *expr6(), *expr7(), *expr8(), *expr9(), *expr10();
40 NODE
*doprint(), *dofuncn(), *doif(), *dowhile(), *dofor(), *body();
41 NODE
*doassign(), *dodo(), *doarray(), *doreturn(), *doelement();
42 CELL
*mkcell(), *getvar();
43 CELL
*execute(), *lookup();
45 int forflg
; /* parsing for(expr in array), inhibit 'expr in array' */
46 int prmflg
; /* parsing pass parameters */
47 NODE
*begin
, *loop
, *End
;
51 NODE
*p
, *q
, *r
, *stat();
67 for (p
= End
; p
; p
= q
) {
68 if ((q
= p
->n_next
) == NULL
)
80 while (sym
&& sym
!= BEGIN
&& sym
!= END
&& sym
!= FUNC
) {
95 while (Getrec(NULL
)) {
108 static char *argnam
[MAXARG
];
116 strcpy(funnam
, text
);
117 u
= getvar(text
, funtab
, FUN
);
120 synerr("'(' expected");
121 for (lex(); sym
!= ')'; narg
++) {
123 synerr("argument expected");
124 argnam
[narg
] = strsave(text
);
129 u
->c_fval
= (double) narg
;
133 u
->c_sval
= (char *) stat();
137 sfree(argnam
[--narg
]);
148 for (i
= narg
- 1; i
>= 0; i
--)
149 if (strcmp(s
, argnam
[i
]) == 0)
163 for (lex(); sym; lex()) {
165 if (p->n_type != PRINT && !iscntl(p->n_type)) {
166 q = (NODE *) emalloc(sizeof(NODE) + sizeof(NODE *) * 4);
168 q->n_arg[0] = q->n_arg[1] = q->n_arg[3] = NULL;
174 printf("[%g(%s)]\n", u->c_fval, u->c_sval);
186 IF
, DO
, WHILE
, FOR
, JUMP
, GETLINE
, 0
190 for (i
= 0; tab
[i
]; i
++)
201 if (sym
== '{') /* action only */
203 else { /* exp [, expr] [{ .. }] */
211 if (sym
&& sym
!= EOL
)
216 p
= node3(P2STAT
, p
, q
, r
);
218 p
= node2(P1STAT
, p
, r
);
230 /*printf("@stat(%d)(%s)\n", sym, text);*/
256 p
= node2(JUMP
, (NODE
*)sym
, (NODE
*)NULL
);
258 if (sym
== IDENT
|| sym
== NUMBER
|| sym
== ARG
)
259 p
->n_arg
[1] = expr();
261 case BREAK
: case CONTIN
: case NEXT
:
262 p
= node1(JUMP
, (NODE
*)sym
);
267 u
= getvar(text
, hashtab
, ARR
);
269 synerr("'[' expected");
293 if (sym
== BINOR
) { /* expr | GETLINE */
296 synerr("'GETLINE' expected");
298 if (sym
== IDENT
|| sym
== STRING
|| sym
== ARG
) {
303 p
= node3(GETLINE
, q
, p
, (NODE
*)R_PIN
);
308 if (p
->n_type
== VALUE
)
309 synerr("statement expected");
332 if (sym
!= '}' && sym
!= ')' && sym
!= EOL
&& sym
!= R_OUT
&& sym
!= R_APD
345 if (sym
== R_OUT
|| sym
== R_APD
|| sym
== R_POUT
) {
349 q
= expr(); /* 94-04-02 */
352 q
= (NODE
*) (op
= 0); /* stdout */
354 r
= (NODE
*) emalloc(sizeof(*r
) + sizeof(r
) * (n
+ 3));
355 r
->n_type
= PRINT
; /* convert list to arg */
357 r
->n_arg
[0] = (NODE
*) (op
| fmt
);
360 p
= node1(VALUE
, (NODE
*)field
[0]);
362 for (i
= 2; p
!= NULL
; i
++) {
379 synerr("'(' expected");
383 synerr("')' expected");
395 return node3(IF
, p
, q
, r
);
405 synerr("'(' expected");
409 synerr("')' expected");
411 return node2(WHILE
, p
, q
);
423 synerr("'(' expected");
426 forflg
++; /* inhibit parsing 'expr IN array' */
436 printf("***FOR_IN_ARG(%d)***\n", sym);
438 u
= mkcell(POS
, NULL
, (double)sym1
);
442 u
= getvar(text
, hashtab
, ARR
);
447 synerr("')' expected");
451 r
= node3(FORIN
, p
, q
, s
);
455 synerr("'in' or ';' expected");
462 synerr("';' expected");
469 synerr("')' expected");
471 r
= node4(FOR
, p
, q
, r
, s
);
481 while ((sym
= Getc()) == '\n' || sym
== ' ' || sym
== '\t')
505 synerr("'while' expected");
508 synerr("'(' expected");
512 synerr("')' expected");
514 return node2(DO
, p
, q
);
535 r
= (NODE
*) emalloc(sizeof(*r
) + sizeof (r
) * (n
+ 1));
538 r
->n_arg
[0] = (NODE
*) RETURN
;
539 for (i
= 1; p
!= NULL
; i
++) {
556 p
= doassign(sym
, p
);
562 return (sym
== ASSIGN
|| sym
== ADDEQ
|| sym
== SUBEQ
|| sym
== MULTEQ
563 || sym
== DIVEQ
|| sym
== MODEQ
|| sym
== POWEQ
);
567 doassign(op
, p
) NODE
*p
;
568 { /* evaluate right to left */
574 q
= doassign(sym
, q
);
575 return node3(ASSIGN
, (NODE
*)op
, p
, q
);
584 printf("expr1(%d)(%s)\n", sym, text);
592 synerr("':' expected");
594 return node3(IF
, p
, q
, stat());
598 synerr("':' expected");
600 return node3(IF
, p
, q
, expr());
603 return p
; /* 930213 */
612 printf("expr2(%d)(%s)\n", sym, text);
618 p
= node3(COND
, (NODE
*)OR
, p
, expr3());
629 printf("expr3(%d)(%s)\n", sym, text);
635 p
= node3(COND
, (NODE
*)AND
, p
, expr4());
648 printf("expr4(%d)(%s)\n", sym, text);
651 if (!forflg
&& sym
== IN
) {
653 q
= getvar(text
, hashtab
, ARR
);
655 return node2(IN
, p
, q
);
657 while (sym
== EQ
|| sym
== NE
|| sym
== LT
|| sym
== LE
|| sym
== GT
658 || sym
== GE
|| sym
== MATCH
|| sym
== NOMATCH
) {
661 p
= node3(COND
, (NODE
*)op
, p
, expr5());
672 printf("expr5(%d)(%s)\n", sym, text);
677 p
= node2(CAT
, p
, q
);
684 static int ctab
[] = {
685 ADD
, SUB
, MULT
, DIV
, MOD
, INC
, DEC
, STRING
, NUMBER
, IDENT
, '(',
686 MATHFUN
, STRFUN
, SPRINTF
, '$', SUBST
, ARG
, CALL
, 0
690 for (i
= 0; j
= ctab
[i
]; i
++)
699 register int sign
= sym
;
703 printf("expr6(%d)(%s)\n", sym, text);
705 if (sym
== SUB
|| sym
== ADD
)
709 p
= node2(ARITH
, (NODE
*)UMINUS
, p
);
710 while (sym
== ADD
|| sym
== SUB
) {
715 p
= node3(ARITH
, (NODE
*)ADD
, p
, q
);
717 else if (sign
== SUB
) {
718 p
= node3(ARITH
, (NODE
*)SUB
, p
, q
);
721 synerr("'+' or '-' expected");
733 printf("expr7(%d)(%s)\n", sym, text);
736 while (sym
== MULT
|| sym
== DIV
|| sym
== MOD
) {
741 case MULT
: p
= node3(ARITH
, (NODE
*)MULT
, p
, q
); break;
742 case DIV
: p
= node3(ARITH
, (NODE
*)DIV
, p
, q
); break;
743 case MOD
: p
= node3(ARITH
, (NODE
*)MOD
, p
, q
); break;
744 default: synerr("'*', '/' or '%' expected"); break;
757 printf("expr8(%d)(%s)\n", sym, text);
761 p
= node2(COND
, (NODE
*)NOT
, expr9());
767 p
= node3(ARITH
, (NODE
*)POWER
, p
, expr9());
780 printf("expr9(%d)(%s)\n", sym, text);
782 if (op
= isincdec(sym
)) {
784 if (sym
!= IDENT
&& sym
!= ARG
)
785 synerr("illegal '++/--' operator");
787 p
= node4(ARITH
, (NODE
*)INCDEC
, p
, (NODE
*)op
, (NODE
*)PRE
);
792 if (op
= isincdec(sym
)) {
793 /*printf("POST(%d)(%d)(%s)\n", sym, sym0, text);*/
794 if (sym0
== IDENT
|| sym0
== ARG
) {
795 p
= node4(ARITH
, (NODE
*)INCDEC
, p
, (NODE
*)op
,
800 if (sym
== BINOR
) { /* | getline */
803 synerr("'GETLINE' expected");
805 if (sym
== IDENT
|| sym
== STRING
|| sym
== ARG
) {
810 p
= node3(GETLINE
, q
, p
, (NODE
*)R_PIN
);
818 return sym
== INC
? 1 : (sym
== DEC
? -1 : 0);
832 printf("expr10(%d)(%s)\n", sym, text);
836 u
= mkcell(STR
, text
, 0.0);
839 u
= mkcell(NUM
, NULL
, atof(text
));
844 case IDENT
: case ARG
:
845 if (isarrayindex()) { /* array */
848 u
= (CELL
*)emalloc(sizeof(CELL
));
849 u
= mkcell(POS
, NULL
, (double)sym1
);
853 u
= getvar(text
, hashtab
, ARR
);
859 u
= mkcell(POS
, NULL
, (double)sym1
);
862 else { /* symple variable */
863 u
= getvar(text
, hashtab
, VAR
|STR
|NUM
);
870 /* print >(x ? y : z) needs this */
871 gsave
= getlineflg
; psave
= printflg
;
872 getlineflg
= printflg
= 0;
875 if (sym
== ',') /* (expr, expr, .. ) */
878 synerr("')' expected");
879 getlineflg
= gsave
; printflg
= psave
;
883 p
= dofuncn(sym
, getvar(text
, funtab
, UDF
));
885 case MATHFUN
: case STRFUN
: case SUBST
:
886 p
= dofuncn(sym
, (CELL
*)sym1
);
889 p
= doprint(FORMAT
|STROUT
);
895 u
= mkcell(NUM
, NULL
, atof(text
));
900 case IDENT
: case ARG
: case '(':
901 p
= node1(FIELD
, expr10());
904 synerr("number or identifier expected after '$'", (char *)0);
911 u
= mkcell(PAT
, NULL
, 0.0);
912 u
->c_sval
= (char *) mkpat(text
);
919 if (sym
== IDENT
|| sym
== STRING
|| sym
== ARG
)
920 q
= expr10(); /* read into var */
930 op
= (int) (p
= NULL
);
931 p
= node3(GETLINE
, q
, p
, (NODE
*)op
);
935 "identifier, number, string, argument, regexpr, call or '(' expected");
942 dofuncn(fun
, op
) CELL
*op
;
951 for (lex(); sym
&& (sym
!= ')'); n
++) {
952 if ((int)op
== SPLIT
&& n
== 1) {
954 printf("sym(%d)sym1(%d)(%d)\n", sym, sym1, isarg(text));
956 if (sym
!= ARG
) { /*isarg(text) == -1*/
957 /* make an array if not exist */
959 getvar(text
, hashtab
, ARR
);
967 synerr("',' or ')' expected");
974 synerr("')' expected");
976 p
= (NODE
*) emalloc(sizeof(*p
) + sizeof(p
) * (n
+ 2));
979 p
->n_arg
[0] = (NODE
*) op
;
980 p
->n_arg
[1] = (NODE
*) n
;
981 for (i
= 0, j
= 2; i
< n
; )
982 p
->n_arg
[j
++] = a
[i
++];
995 for (lex(), n
= 0; sym
&& sym
!= ']'; n
++) {
1001 synerr("']' expected");
1002 /* left ']' for expr10() */
1003 p
= (NODE
*) emalloc(sizeof(*p
) + sizeof(p
) * (n
+ 1));
1006 p
->n_arg
[0] = (NODE
*)u
;
1007 p
->n_arg
[1] = (NODE
*) n
;
1008 for (i
= 0, j
= 2; i
< n
; )
1009 p
->n_arg
[j
++] = a
[i
++];
1014 doelement(q
) NODE
*q
;
1022 for (lex(), n
= 1; sym
&& sym
!= ')'; n
++) {
1026 else if (sym
!= ')')
1027 synerr("',' or ')' expected");
1029 /* left ')' for expr10() */
1030 p
= (NODE
*) emalloc(sizeof(*p
) + sizeof(p
) * (n
+ 1));
1031 p
->n_type
= ELEMENT
;
1034 p
->n_arg
[1] = (NODE
*) n
;
1035 for (i
= 0, j
= 2; i
< n
; )
1036 p
->n_arg
[j
++] = a
[i
++];
1040 synerr(s
, t
) char *s
, *t
;
1043 extern char line
[], *linep
;
1047 fprintf(stderr
, "%s: Syntax error at line %d", cmd
, lineno
);
1049 fprintf(stderr
, " in function %s", funnam
);
1050 fprintf(stderr
, ":\n");
1051 if ((v
= linep
- 1) < line
)
1052 v
= line
+ BUFSIZ
- 1;
1053 for (i
= 0, u
= v
- 1; ; --u
) {
1055 if (line
[BUFSIZ
- 1] == '\0')
1057 u
= line
+ BUFSIZ
- 1;
1059 if (*u
== '\n' && ++i
== 2)
1065 if ((++u
- line
) == BUFSIZ
)
1070 fprintf(stderr
, " <--\n\n");
1072 fprintf(stderr, " <-- ");
1073 while ((c = Getc()) != EOF && c != '\n')
1075 fprintf(stderr, "\n");
1077 fprintf(stderr, "\n");
1080 fprintf(stderr
, s
, t
);
1081 fprintf(stderr
, "\n");