first in 2.5.10 series
[k8jam.git] / src / parse.c
blob9bb93292c49da755b544286a7f753772f096dfac
1 /*
2 * Copyright 1993, 2000 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
7 /*
8 * parse.c - make and destroy parse trees as driven by the parser
10 * 09/07/00 (seiwald) - ref count on PARSE to avoid freeing when used,
11 * as per Matt Armstrong.
12 * 09/11/00 (seiwald) - structure reworked to reflect that (*func)()
13 * returns a LIST *.
14 * 10/22/02 (seiwald) - working return/break/continue statements
15 * 11/04/02 (seiwald) - const-ing for string literals
17 #include "jam.h"
18 #include "lists.h"
19 #include "parse.h"
20 #include "scan.h"
21 #include "newstr.h"
24 static PARSE *yypsave;
26 void parse_file (const char *f) {
27 /* suspend scan of current file and push this new file in the stream */
28 yyfparse(f);
29 /* now parse each block of rules and execute it */
30 /* execute it outside of the parser so that recursive */
31 /* calls to yyrun() work (no recursive yyparse's) */
32 for (;;) {
33 LOL l;
34 PARSE *p;
35 int jmp = 0; /* JMP_NONE */
36 /* $(<) and $(>) empty in outer scope */
37 lol_init(&l);
38 /* filled by yyparse() calling parse_save() */
39 yypsave = 0;
40 /* if parse error or empty parse, outta here */
41 if (yyparse() || !(p = yypsave)) break;
42 /* run the parse tree */
43 list_free((*(p->func))(p, &l, &jmp));
44 parse_free(p);
49 void parse_save (PARSE *p) {
50 yypsave = p;
54 PARSE *parse_make (
55 LIST *(*func) (PARSE *p, LOL *args, int *jmp),
56 PARSE *left,
57 PARSE *right,
58 PARSE *third,
59 const char *string,
60 const char *string1,
61 int num)
63 PARSE *p = (PARSE *)malloc(sizeof(PARSE));
64 p->func = func;
65 p->left = left;
66 p->right = right;
67 p->third = third;
68 p->string = string;
69 p->string1 = string1;
70 p->num = num;
71 p->refs = 1;
72 return p;
76 void parse_refer (PARSE *p) {
77 ++p->refs;
81 void parse_free (PARSE *p) {
82 if (--p->refs) return;
83 if (p->string) freestr( p->string );
84 if (p->string1) freestr( p->string1 );
85 if (p->left) parse_free( p->left );
86 if (p->right) parse_free( p->right );
87 if (p->third) parse_free( p->third );
88 free((char *)p);
92 const char *multiFormSfx (int cnt) {
93 return cnt==1?"":"s";