4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
11 allocStmt(Stmt *par, int type)
13 Stmt *st = zalloc(sizeof(Stmt));
16 st->st_Run = RunUnresolvedStmt;
17 st->st_Gen = GenUnresolvedStmt;
18 RUNE_INIT(&st->st_List);
21 st->st_Run = par->st_Run;
22 RUNE_INSERT_TAIL(&par->st_List, st, st_Node);
28 PushStmt(Parse *p, Stmt **pst, int type, int flags)
48 st = allocStmt(p->p_CurStmt, type);
49 st->st_Flags |= flags;
50 LexInitRef(&st->st_LexRef, &p->p_Token);
54 if (st->st_Flags & STF_SEMANTIC) {
55 SemGroup *sg = AllocSemGroup(sgtype, p, p->p_CurSemGroup, st);
56 p->p_CurSemGroup = sg;
57 if (st->st_Flags & STF_SEMTOP) {
58 sg->sg_Flags |= SGF_SEMTOP;
59 if (st->st_Flags & STF_NESTED) {
61 sg->sg_Parent->sg_NestLevel + 1;
62 sg->sg_Flags |= SGF_NESTED;
66 AdjustNestSize(sg, sg->sg_NestLevel + 1);
69 st->st_MyGroup = p->p_CurSemGroup;
75 PopStmt(Parse *p, Stmt *st)
77 dassert_stmt(st, p->p_CurStmt == st);
78 p->p_CurStmt = st->st_Parent;
80 if (st->st_Flags & STF_SEMANTIC) {
81 dassert_stmt(st, p->p_CurSemGroup == st->st_MyGroup);
82 p->p_CurSemGroup = st->st_MyGroup->sg_Parent;
88 DupStmt(SemGroup *sg, Stmt *par, Stmt *sst)
97 st = allocStmt(par, sst->st_Op);
99 LexDupRef(&sst->st_LexRef, &st->st_LexRef);
100 st->st_Flags |= sst->st_Flags;
101 st->st_Flags &= ~(STF_RESOLVING | STF_RESOLVED | STF_TMPRESOLVED |
103 if (st->st_Flags & STF_SEMANTIC) {
104 st->st_MyGroup = sg = DupSemGroup(sg, st, sst->st_MyGroup, 0);
111 * An import statement is never dup'd
114 st->st_ImportStmt.es_Parser = sst->st_ImportStmt.es_Parser;
115 st->st_ImportStmt.es_Path =
116 StrTableDup(sst->st_ImportStmt.es_Path);
117 st->st_ImportStmt.es_AsId =
118 StrTableDup(sst->st_ImportStmt.es_AsId);
120 dassert_stmt(sst, 0);
123 * note: declaration is placed in parent SemGroup
128 st->st_TypedefStmt.es_Decl =
129 DupDeclaration(sg, sst->st_TypedefStmt.es_Decl);
133 * YYY duplicate multiple declarations
135 * Procedure definitions will have sub-statements
136 * (under st->st_List), but we do not duplicate it here.
138 st->st_DeclStmt.es_Decl =
139 DupDeclaration(sg, sst->st_DeclStmt.es_Decl);
140 st->st_DeclStmt.es_Decl->d_Stmt = st;
141 st->st_DeclStmt.es_DeclCount = 1;
142 st->st_DeclStmt.es_Scope = sst->st_DeclStmt.es_Scope;
143 d = sst->st_DeclStmt.es_Decl;
144 while (st->st_DeclStmt.es_DeclCount <
145 sst->st_DeclStmt.es_DeclCount)
149 d = RUNE_NEXT(d, d_Node);
150 dassert_stmt(st, d->d_Stmt == sst);
151 nd = DupDeclaration(sg, d);
153 ++st->st_DeclStmt.es_DeclCount;
156 d = st->st_DeclStmt.es_Decl;
157 if (d->d_Op == DOP_PROC) {
158 if (sg->sg_Stmt->st_Op != ST_Class) {
159 scan = getHead(&sst->st_List);
161 scan && scan->st_Op == ST_Proc);
163 getSucc(&sst->st_List,
164 &scan->st_Node) == NULL);
165 /* DupStmt(sg, st, scan);*/
166 d->d_ProcDecl.ed_OrigBody = scan;
169 dassert_stmt(st, listIsEmpty(&st->st_List));
175 * Procedure bodies are usually only duplicated from
176 * resolveDecl() on-demand (see ST_Decl case above).
177 * Otherwise we would have a billion copies of a procedure
178 * due to subclassing, so this case does not normally occur
179 * until the actual procedure is referenced.
181 * Also note that the resolution on demand will change the
182 * ordering of the statements within its parent statement
183 * (typically a Class statement).
185 * If the procedure was inlined we must copy the
186 * already-resolved es_Decl and es_Scope, if not inlined
187 * the resolver will [re]calculate it.
189 if (sst->st_Flags & STF_INLINED_PROC) {
190 st->st_ProcStmt.es_Decl = sst->st_ProcStmt.es_Decl;
191 st->st_ProcStmt.es_Scope = sst->st_ProcStmt.es_Scope;
195 if (sst->st_Op == ST_Block && sst->st_BlockStmt.es_BlockId) {
196 st->st_BlockStmt.es_BlockId =
197 StrTableDup(sst->st_BlockStmt.es_BlockId);
199 RUNE_FOREACH(scan, &sst->st_List, st_Node) {
200 DupStmt(sg, st, scan);
206 st->st_LoopStmt.es_Init =
207 DupStmt(sg, st, sst->st_LoopStmt.es_Init);
208 st->st_LoopStmt.es_BCond =
209 SetDupExp(sg, sst->st_LoopStmt.es_BCond);
210 st->st_LoopStmt.es_ACond =
211 SetDupExp(sg, sst->st_LoopStmt.es_ACond);
212 st->st_LoopStmt.es_AExp =
213 SetDupExp(sg, sst->st_LoopStmt.es_AExp);
214 st->st_LoopStmt.es_Body =
215 DupStmt(sg, st, sst->st_LoopStmt.es_Body);
218 st->st_BreakStmt.es_IsCont = sst->st_BreakStmt.es_IsCont;
219 st->st_BreakStmt.es_Count = sst->st_BreakStmt.es_Count;
220 st->st_BreakStmt.es_StmtType = sst->st_BreakStmt.es_StmtType;
221 if (sst->st_BreakStmt.es_BlockId) {
222 st->st_BreakStmt.es_BlockId =
223 StrTableDup(sst->st_BreakStmt.es_BlockId);
229 st->st_IfStmt.es_Exp =
230 SetDupExp(sg, sst->st_IfStmt.es_Exp);
231 st->st_IfStmt.es_TrueStmt =
232 DupStmt(sg, st, sst->st_IfStmt.es_TrueStmt);
233 st->st_IfStmt.es_FalseStmt =
234 DupStmt(sg, st, sst->st_IfStmt.es_FalseStmt);
237 st->st_RetStmt.es_Count = sst->st_RetStmt.es_Count;
238 st->st_RetStmt.es_Exp = SetDupExp(sg, sst->st_RetStmt.es_Exp);
241 st->st_ResStmt.es_Count = sst->st_ResStmt.es_Count;
242 st->st_ResStmt.es_Exp = SetDupExp(sg, sst->st_ResStmt.es_Exp);
245 st->st_SwStmt.es_Exp = SetDupExp(sg, sst->st_SwStmt.es_Exp);
246 RUNE_FOREACH(scan, &sst->st_List, st_Node) {
247 dassert_stmt(scan, scan->st_Op == ST_Case);
248 if (scan->st_CaseStmt.es_Exp == NULL) {
249 st->st_SwStmt.es_Default =
250 DupStmt(sg, st, scan);
252 DupStmt(sg, st, scan);
257 st->st_CaseStmt.es_Exp = SetDupExp(sg, sst->st_CaseStmt.es_Exp);
258 RUNE_FOREACH(scan, &sst->st_List, st_Node) {
259 DupStmt(sg, st, scan);
263 st->st_ThreadSchedStmt.es_Mode =
264 sst->st_ThreadSchedStmt.es_Mode;
267 st->st_ExpStmt.es_Exp = SetDupExp(sg, sst->st_ExpStmt.es_Exp);
270 dassert_stmt(sst, 0);
278 dassert_stmt(st, st->st_Parent == NULL);
281 while ((st2 = RUNE_FIRST(&st->st_List)) != NULL) {
282 RUNE_REMOVE(&st->st_List, st2, st_Node);
283 st2->st_Parent = NULL;
287 zfree(st, sizeof(Stmt));
291 * BuildRootImportStmt()
293 * Note that st_LexRef will be set by ParseModule(). There is no
294 * SemGroup for the fake root import statement. The real SemGroup
295 * starts at the ST_Module that will be generated under the import
298 * If executed with insufficient path information to identify the
299 * directory, attempt to locate the directory via the $PATH env.
302 BuildRootImportStmt(const char *path)
304 Stmt *st = allocStmt(NULL, ST_Import);
307 if ((epath = strrchr(path, '/')) != NULL) {
309 safe_asprintf(&st->st_ImportStmt.es_Path, "%*.*s",
310 epath - path, epath - path, path);
311 st->st_ImportStmt.es_File = safe_strdup(epath);
313 st->st_ImportStmt.es_Path = safe_strdup("");
314 st->st_ImportStmt.es_File = safe_strdup(path);
317 st->st_Flags = STF_SEMANTIC|STF_SEMTOP|STF_FORWARD;
318 st->st_MyGroup = AllocSemGroup(XXX, NULL, NULL, st);
324 StmtPrintError(Stmt *st, int type)
326 LexPrintRef(&st->st_LexRef, type);