]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * Copyright 1993, 2000 Christopher Seiwald. | |
3 | * | |
4 | * This file is part of Jam - see jam.c for Copyright information. | |
5 | */ | |
6 | ||
7 | /* This file is ALSO: | |
8 | * Copyright 2001-2004 David Abrahams. | |
9 | * Distributed under the Boost Software License, Version 1.0. | |
10 | * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) | |
11 | */ | |
12 | ||
13 | #include "jam.h" | |
14 | #include "lists.h" | |
15 | #include "parse.h" | |
16 | #include "scan.h" | |
17 | #include "object.h" | |
18 | #include "modules.h" | |
19 | #include "frames.h" | |
20 | #include "function.h" | |
21 | ||
22 | /* | |
23 | * parse.c - make and destroy parse trees as driven by the parser | |
24 | * | |
25 | * 09/07/00 (seiwald) - ref count on PARSE to avoid freeing when used, | |
26 | * as per Matt Armstrong. | |
27 | * 09/11/00 (seiwald) - structure reworked to reflect that (*func)() | |
28 | * returns a LIST *. | |
29 | */ | |
30 | ||
31 | static PARSE * yypsave; | |
32 | ||
b32b8144 | 33 | static void parse_impl( FRAME * frame ) |
7c673cae | 34 | { |
7c673cae FG |
35 | |
36 | /* Now parse each block of rules and execute it. Execute it outside of the | |
37 | * parser so that recursive calls to yyrun() work (no recursive yyparse's). | |
38 | */ | |
39 | ||
40 | for ( ; ; ) | |
41 | { | |
42 | PARSE * p; | |
43 | FUNCTION * func; | |
44 | ||
45 | /* Filled by yyparse() calling parse_save(). */ | |
46 | yypsave = 0; | |
47 | ||
48 | /* If parse error or empty parse, outta here. */ | |
49 | if ( yyparse() || !( p = yypsave ) ) | |
50 | break; | |
51 | ||
52 | /* Run the parse tree. */ | |
53 | func = function_compile( p ); | |
54 | parse_free( p ); | |
55 | list_free( function_run( func, frame, stack_global() ) ); | |
56 | function_free( func ); | |
57 | } | |
58 | ||
59 | yyfdone(); | |
60 | } | |
61 | ||
62 | ||
b32b8144 FG |
63 | void parse_file( OBJECT * f, FRAME * frame ) |
64 | { | |
65 | /* Suspend scan of current file and push this new file in the stream. */ | |
66 | yyfparse( f ); | |
67 | ||
68 | parse_impl( frame ); | |
69 | } | |
70 | ||
71 | ||
72 | void parse_string( OBJECT * name, const char * * lines, FRAME * frame ) | |
73 | { | |
74 | yysparse( name, lines ); | |
75 | parse_impl( frame ); | |
76 | } | |
77 | ||
78 | ||
7c673cae FG |
79 | void parse_save( PARSE * p ) |
80 | { | |
81 | yypsave = p; | |
82 | } | |
83 | ||
84 | ||
85 | PARSE * parse_make( | |
86 | int type, | |
87 | PARSE * left, | |
88 | PARSE * right, | |
89 | PARSE * third, | |
90 | OBJECT * string, | |
91 | OBJECT * string1, | |
92 | int num ) | |
93 | { | |
94 | PARSE * p = (PARSE *)BJAM_MALLOC( sizeof( PARSE ) ); | |
95 | ||
96 | p->type = type; | |
97 | p->left = left; | |
98 | p->right = right; | |
99 | p->third = third; | |
100 | p->string = string; | |
101 | p->string1 = string1; | |
102 | p->num = num; | |
103 | p->refs = 1; | |
104 | p->rulename = 0; | |
105 | ||
106 | if ( left ) | |
107 | { | |
108 | p->file = object_copy( left->file ); | |
109 | p->line = left->line; | |
110 | } | |
111 | else | |
112 | { | |
113 | yyinput_last_read_token( &p->file, &p->line ); | |
114 | p->file = object_copy( p->file ); | |
115 | } | |
116 | ||
117 | return p; | |
118 | } | |
119 | ||
120 | ||
121 | void parse_refer( PARSE * p ) | |
122 | { | |
123 | ++p->refs; | |
124 | } | |
125 | ||
126 | ||
127 | void parse_free( PARSE * p ) | |
128 | { | |
129 | if ( --p->refs ) | |
130 | return; | |
131 | ||
132 | if ( p->string ) | |
133 | object_free( p->string ); | |
134 | if ( p->string1 ) | |
135 | object_free( p->string1 ); | |
136 | if ( p->left ) | |
137 | parse_free( p->left ); | |
138 | if ( p->right ) | |
139 | parse_free( p->right ); | |
140 | if ( p->third ) | |
141 | parse_free( p->third ); | |
142 | if ( p->rulename ) | |
143 | object_free( p->rulename ); | |
144 | if ( p->file ) | |
145 | object_free( p->file ); | |
146 | ||
147 | BJAM_FREE( (char *)p ); | |
148 | } |