4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
10 static int ParseImportStmt(Parse *p, int t, Scope *scope);
11 static int ParseClassStmt(Parse *p, int t, Scope *scope);
12 static int ParseSubClassStmt(Parse *p, int t, Scope *scope);
13 static int ParseProjectStmt(Parse *p, int t, Scope *scope);
14 static int ParseBlockStmt(Parse *p, int t, Stmt **pst);
15 static int ParseProcStmt(Parse *p, int t, Declaration *d, Stmt **pst);
16 static int ParseForStmt(Parse *p, int t, Stmt **pst);
17 static int ParseWhileStmt(Parse *p, int t, Stmt **pst);
18 static int ParseUntilStmt(Parse *p, int t, Stmt **pst);
19 static int ParseDoStmt(Parse *p, int t, Stmt **pst);
20 static int ParseBreakContStmt(Parse *p, int t, Stmt **pst);
21 static int ParseSwitchStmt(Parse *p, int t, Stmt **pst);
22 static int ParseIfElseStmt(Parse *p, int t, Stmt **pst);
23 static int ParseReturnStmt(Parse *p, int t, Stmt **pst);
24 static int ParseResultStmt(Parse *p, int t, Stmt **pst);
25 static int ParseNopStmt(Parse *p, int t, Stmt **pst);
26 static int ParseExpStmt(Parse *p, int t, Stmt **pst);
27 static int ParseThreadSchedStmt(Parse *p, int t, Stmt **pst);
29 static int distinguishDeclaration(Parse *p, int t);
32 * Merge default scope for semantic layer with per-declaration scope.
36 mergeScope(Scope *src, Scope *dst)
38 dst->s_Flags |= src->s_Flags;
39 if (dst->s_AlignOverride == 0)
40 dst->s_AlignOverride = src->s_AlignOverride;
44 * ParseModule() - parse the body of an imported entity.
46 * This function is called from the top level utility to bring in
47 * initial source module, and is called by ParseImport() to import
48 * a new module. We create a placeholder statement to represent
49 * the entire module. Also note that the semantic group will be
50 * associated with the new Parse zone, but is still linked to the
53 * Note that all declarations made at the import level are automatically
57 ParseModule(Parse *p, Stmt *stpar, int t)
61 Scope save_scope = { 0, 0 };
63 dassert_stmt(stpar, stpar->st_Op == ST_Import);
65 st = PushStmt(p, NULL, ST_Module,
66 STF_SEMANTIC | STF_SEMTOP | STF_FORWARD);
67 dassert(stpar->st_Op == ST_Import);
70 * Glue to the parent that imported us. Note that ed_SemGroup will be
71 * NULL for shared-library (.so) imports, since this code is never
72 * reached in that case.
74 stpar->st_ImportStmt.es_SemGroup = st->st_MyGroup;
75 if ((d = stpar->st_ImportStmt.es_Decl) != NULL)
76 d->d_ImportDecl.ed_SemGroup = st->st_MyGroup;
79 if (st->st_LexRef.lr_Lex == NULL)
80 LexInitRef(&st->st_LexRef, &p->p_Token);
82 while ((t & TOKF_ERREOF) == 0) {
85 t = ParseScopeQual(p, t, &scope);
90 t = LexToken(&p->p_Token);
93 scope.s_Flags |= SCOPE_GLOBAL;
94 mergeScope(&save_scope, &scope);
95 t = ParseImportStmt(p, t, &scope);
98 scope.s_Flags |= SCOPE_GLOBAL;
99 scope.s_Flags |= SCOPE_INTERFACE;
102 scope.s_Flags |= SCOPE_GLOBAL;
103 mergeScope(&save_scope, &scope);
104 t = ParseClassStmt(p, t, &scope);
106 case TOK_SUBINTERFACE:
107 scope.s_Flags |= SCOPE_GLOBAL;
108 scope.s_Flags |= SCOPE_INTERFACE;
111 scope.s_Flags |= SCOPE_GLOBAL;
112 mergeScope(&save_scope, &scope);
113 t = ParseSubClassStmt(p, t, &scope);
116 mergeScope(&save_scope, &scope);
117 t = ParseProjectStmt(p, t, &scope);
120 scope.s_Flags |= SCOPE_GLOBAL;
121 mergeScope(&save_scope, &scope);
122 t = ParseTypedefStmt(p, t, &scope);
127 * NOTE: dop is overridden by TOK_ALIAS and other
128 * scope flags such as SCOPE_GLOBAL.
130 * NOTE: We do not set SCOPE_GLOBAL here, because
131 * the declaration might be contextually in
132 * a class (e.g. Fd.setfd). It will be handled
135 mergeScope(&save_scope, &scope);
136 t = ParseDeclarationStmt(p, t, 2, NULL,
137 DOP_GROUP_STORAGE, &scope);
141 if ((t & TOKF_ERROR) == 0)
142 p->p_Format = PFMT_PARSED;
149 ParseStmt(Parse *p, int t, Stmt **pst)
153 t = ParseBlockStmt(p, t, pst);
156 t = ParseForStmt(p, t, pst);
159 t = ParseWhileStmt(p, t, pst);
162 t = ParseUntilStmt(p, t, pst);
165 t = ParseDoStmt(p, t, pst);
169 t = ParseBreakContStmt(p, t, pst);
172 t = ParseSwitchStmt(p, t, pst);
174 case TOK_THREAD_SCHEDULE:
175 t = ParseThreadSchedStmt(p, t, pst);
178 t = ParseIfElseStmt(p, t, pst);
181 t = LexError(&p->p_Token, TOK_ERR_ELSE_WITHOUT_IF);
186 t = ParseReturnStmt(p, t, pst);
189 t = ParseResultStmt(p, t, pst);
192 t = LexError(&p->p_Token, TOK_ERR_CASE_WITHOUT_SWITCH);
197 t = ParseNopStmt(p, t, pst);
200 t = LexError(&p->p_Token, TOK_ERR_DEFAULT_WITHOUT_SWITCH);
206 * Parse a declaration or an expression. Declarations are
207 * distinguished from expressions by beginning with a scope
208 * qualifier, "alias", or a class identifier.
210 if ((t & (TOKF_STOR_QUAL|TOKF_SCOPE_QUAL)) ||
212 distinguishDeclaration(p, t)
217 * NOTE: TOK_ALIAS will override the passed-in dop
220 t = ParseScopeQual(p, t, &scope);
221 t = ParseDeclarationStmt(p, t, 1, pst,
222 DOP_STACK_STORAGE, &scope);
224 t = ParseExpStmt(p, t, pst);
231 * Return non-zero to parse as a declaration
234 distinguishDeclaration(Parse *p, int t)
236 token_t tok = p->p_Token;
239 * Possible compound declaration.
241 if (t == TOK_OPAREN) {
243 while (count && ((t = LexToken(&tok)) & TOKF_ERROR) == 0) {
244 /* check comma to detect compound type */
245 if (t == TOK_COMMA && count == 1)
254 } else if ((t & TOKF_ID) == 0) {
259 while ((nt = LexToken(&tok)) == TOK_DOT) {
261 if ((nt & TOKF_ID) == 0)
270 if (t == TOK_CLASSID)
278 if (t == TOK_OPER && tok.t_Ptr[0] == '*')
285 * import "path" [ as id ];
289 ParseImportStmt(Parse *p, int t, Scope *scope)
293 t = LexSkipToken(&p->p_Token, TOK_IMPORT);
295 if (StrCmpToken(String_SelfContained, &p->p_Token) == 0) {
297 while (st->st_Op != ST_Module)
299 if ((st->st_Flags & STF_SELFCONTAINED) == 0) {
300 st->st_Flags |= STF_SELFCONTAINED;
301 st->st_MyGroup->sg_Flags |= SGF_SELFCONTAINED;
303 dassert(st->st_Op == ST_Import);
304 SetSharedImport(&p->p_St,
305 st->st_ImportStmt.es_SemGroup);
307 t = LexToken(&p->p_Token);
308 t = LexSkipToken(&p->p_Token, TOK_SEMI);
310 t = LexError(&p->p_Token, TOK_ERR_SYNTAX);
315 st = PushStmt(p, NULL, ST_Import, STF_SEMANTIC|STF_SEMTOP|STF_FORWARD);
317 st = PushStmt(p, NULL, ST_Import, 0);
319 if (t == TOK_DSTRING) {
324 LexStripQuotes(&p->p_Token, &tmp);
325 path = StrTableToken(&tmp);
326 if ((ptr = strrchr(path, '/')) != NULL) {
329 &st->st_ImportStmt.es_Path,
335 st->st_ImportStmt.es_File = safe_strdup(ptr);
336 dassert_parse(p, TOK_ERR_EMPTY_PATH, *ptr != 0);
338 st->st_ImportStmt.es_Path = safe_strdup("");
339 st->st_ImportStmt.es_File = safe_strdup(path);
342 t = LexToken(&p->p_Token);
345 t = LexToken(&p->p_Token);
348 * Special case allows inherent downward
351 st->st_ImportStmt.es_AsId =
352 StrTableToken(&p->p_Token);
353 t = LexToken(&p->p_Token);
354 } else if (t & TOKF_ID) {
355 st->st_ImportStmt.es_AsId =
356 StrTableToken(&p->p_Token);
357 t = LexToken(&p->p_Token);
359 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_ID);
365 str = StripPathId(st->st_ImportStmt.es_File, &len);
366 st->st_ImportStmt.es_AsId = StrTableAlloc(str, len, 0);
369 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_STRING);
373 * Parse the imported entity (XXX unless shared and already parsed)
375 * NOTE! ParseOpen() is responsible for allocating st_MyGroup
377 if ((t & TOKF_ERROR) == 0) {
381 &st->st_ImportStmt.es_Parser,
382 &st->st_ImportStmt.es_DLL);
383 if (t2 & TOKF_ERROR) {
384 t = LexError(&p->p_Token, t2);
385 } else if (t2 == 0 && (st->st_Flags & STF_SHARED)) {
387 * Assign d_Stmt so a DLL import can find the DLL
388 * (which is stored in the ImportStmt). Note that
389 * ed_SemGroup may be NULL if the import represents
392 * XXX st_MyGroup was overriden, free original?
394 st->st_ImportStmt.es_Decl = AllocImportDecl(st, scope);
395 st->st_ImportStmt.es_Decl->d_ImportDecl.ed_SemGroup =
396 st->st_ImportStmt.es_SemGroup;
397 st->st_ImportStmt.es_Decl->d_Stmt = st;
399 st->st_ImportStmt.es_Decl = AllocImportDecl(st, scope);
400 st->st_ImportStmt.es_Decl->d_Stmt = st;
401 t2 = ParseModule(st->st_ImportStmt.es_Parser, st, t2);
402 if (t2 & TOKF_ERROR) {
404 &st->st_ImportStmt.es_Parser->p_Token);
405 t = LexError(&p->p_Token,
406 TOK_ERR_IMPORT_FAILED);
409 ParseDone(st->st_ImportStmt.es_Parser);
415 t = LexSkipToken(&p->p_Token, TOK_SEMI);
421 * ParseClassStmt() - parse a class or subclass.
426 ParseClassStmt(Parse *p, int t, Scope *scope)
428 Stmt *st = PushStmt(p, NULL, ST_Class,
429 STF_SEMANTIC | STF_SEMTOP | STF_FORWARD);
432 * Get the dotted id path. Extract the last identifier into id
433 * (it will not be counted by count or appear in the returned array).
435 t = LexSkipToken(&p->p_Token, t); /* class or interface */
436 if (t != TOK_CLASSID) {
437 /*if ((t & TOKF_ID) == 0)*/
438 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_CLASSID);
441 Scope save_scope = { 0, 0 };
443 id = StrTableToken(&p->p_Token); /* retrieve the id */
444 t = LexToken(&p->p_Token);
446 st->st_ClassStmt.es_Decl = AllocClassDecl(st, id, NULL, scope);
447 st->st_ClassStmt.es_Super = NULL;
449 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
450 while ((t & TOKF_ERROR) == 0 && t != TOK_CBRACE) {
453 t = ParseScopeQual(p, t, &scope2);
457 t = LexToken(&p->p_Token);
460 mergeScope(&save_scope, &scope2);
461 t = ParseTypedefStmt(p, t, &scope2);
466 * NOTE: dop is overridden by TOK_ALIAS and
467 * other scope flags such as
470 mergeScope(&save_scope, &scope2);
471 t = ParseDeclarationStmt(p, t, 1, NULL,
477 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
479 if (scope->s_Flags & SCOPE_INTERNAL)
480 t = InternalClassAttach(p, t, st->st_ClassStmt.es_Decl);
488 * ParseSubClassStmt() - parse a class or subclass.
490 * subclass id[.id]* as id { ... }
493 ParseSubClassStmt(Parse *p, int t, Scope *scope)
495 Stmt *st = PushStmt(p, NULL, ST_Class,
496 STF_SEMANTIC | STF_SEMTOP | STF_FORWARD);
503 * Get the dotted id path. Extract the last identifier into id
504 * (it will not be counted by count or appear in the returned array).
506 t = LexSkipToken(&p->p_Token, t); /* subclass or subinterface */
507 t = ParseDotIdAry(p, t, &ary, &count, <);
512 * XXX free array on error
514 if (lt != TOK_CLASSID)
515 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_CLASSID);
516 if ((t & TOKF_ERROR) == 0) {
517 t = LexSkipToken(&p->p_Token, TOK_AS);
519 id = StrTableToken(&p->p_Token); /* retrieve the id */
520 t = LexToken(&p->p_Token);
522 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_ID);
527 * Figure out the superclass, if any.
529 if ((t & TOKF_ERROR) == 0) {
532 Scope save_scope = { 0, 0 };
534 isg = p->p_Import->st_ImportStmt.es_SemGroup;
535 super = AllocUnresolvedType(isg, p->p_CurSemGroup, ary, 1);
537 st->st_ClassStmt.es_Decl = AllocClassDecl(st, id, super, scope);
538 st->st_ClassStmt.es_Super = super;
540 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
541 while ((t & TOKF_ERROR) == 0 && t != TOK_CBRACE) {
544 t = ParseScopeQual(p, t, &scope2);
548 t = LexToken(&p->p_Token);
551 mergeScope(&save_scope, &scope2);
552 t = ParseTypedefStmt(p, t, &scope2);
557 * NOTE: dop is overridden by TOK_ALIAS and
558 * other scope flags such as
561 mergeScope(&save_scope, &scope2);
562 t = ParseDeclarationStmt(p, t, 1, NULL,
568 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
570 if (scope->s_Flags & SCOPE_INTERNAL)
571 t = InternalClassAttach(p, t, st->st_ClassStmt.es_Decl);
578 * ParseProjectStmt() - Set project name for shared persistent variables
581 ParseProjectStmt(Parse *p, int t, Scope *scope __unused)
585 sg = p->p_CurSemGroup;
587 t = LexSkipToken(&p->p_Token, TOK_PROJECT);
588 if (t == TOK_DSTRING) {
591 RelStrTable(&sg->sg_Project);
592 LexStripQuotes(&p->p_Token, &tmp);
593 sg->sg_Project = StrTableToken(&tmp);
594 t = LexToken(&p->p_Token);
596 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_STRING);
598 t = LexSkipToken(&p->p_Token, TOK_SEMI);
603 * ParseTypedefStmt() - parse a typedef
605 * Note that we have to give the typedef global scope so use of the
606 * typedef can occur out of the current context. XXX
609 ParseTypedefStmt(Parse *p, int t, Scope *scope)
611 Stmt *st = PushStmt(p, NULL, ST_Typedef, 0);
613 Scope tscope = *scope;
615 t = LexSkipToken(&p->p_Token, TOK_TYPEDEF);
617 tscope.s_Flags |= SCOPE_GLOBAL;
619 t = ParseDeclaration(p, t, &d, 2, DOP_TYPEDEF, &tscope);
620 if ((t & TOKF_ERROR) == 0) {
621 Type *type = d->d_StorDecl.ed_Type;
622 Exp *exp = d->d_StorDecl.ed_AssExp;
624 d->d_Op = DOP_TYPEDEF;
625 d->d_TypedefDecl.ed_Type = TypeToQualType(type,
629 if (tscope.s_Flags & SCOPE_INTERNAL)
630 InternalTypeAttach(p, t, d);
631 st->st_TypedefStmt.es_Decl = d; /* short cut */
633 t = LexSkipToken(&p->p_Token, TOK_SEMI);
639 ParseBlockStmt(Parse *p, int t, Stmt **pst)
641 Stmt *st = PushStmt(p, pst, ST_Block, STF_SEMANTIC);
643 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
644 while ((t & TOKF_ERROR) == 0 && t != TOK_CBRACE) {
645 t = ParseStmt(p, t, NULL);
647 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
653 * ParseProcStmt() - process a procedure body
655 * Due to dotted id handling, the current SemGroup may not be
656 * the SemGroup the declaration was placed in. We have to temporarily
657 * switch to the other semgroup in order to process the procedure
660 * If this is a nested procedure we have to mark it as such.
661 * Note that STF_SEMTOP is used for storage management and is
662 * still set for a nested procedure (it's local storage is
663 * independant of its parent).
667 ParseProcStmt(Parse *p, int t, Declaration *d, Stmt **pst)
672 int flags = STF_SEMANTIC|STF_SEMTOP;
674 save = p->p_CurSemGroup;
675 p->p_CurSemGroup = d->d_MyGroup;
677 for (scan = d->d_MyGroup; scan; scan = scan->sg_Parent) {
678 if ((st = scan->sg_Stmt) != NULL && (st->st_Flags & STF_SEMTOP)) {
679 if (st->st_Op == ST_Proc)
685 st = PushStmt(p, pst, ST_Proc, flags);
686 st->st_DeclStmt.es_Decl = d;
687 st->st_DeclStmt.es_DeclCount = 1;
688 st->st_DeclStmt.es_Scope = d->d_Scope;
689 AdjustProcArgsNestingLevel(d, st->st_MyGroup);
691 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
692 while ((t & TOKF_ERROR) == 0 && t != TOK_CBRACE) {
693 t = ParseStmt(p, t, NULL);
695 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
697 p->p_CurSemGroup = save;
703 ParseForStmt(Parse *p, int t, Stmt **pst)
705 Stmt *st = PushStmt(p, pst, ST_Loop, STF_SEMANTIC);
707 t = LexSkipToken(&p->p_Token, TOK_FOR);
708 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
710 /* note: semicolon implied by statement parser */
711 t = ParseStmt(p, t, &st->st_LoopStmt.es_Init);
713 t = ParseExp(p, t, &st->st_LoopStmt.es_BCond);
714 t = LexSkipToken(&p->p_Token, TOK_SEMI);
716 t = ParseExp(p, t, &st->st_LoopStmt.es_AExp);
717 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
718 t = ParseStmt(p, t, &st->st_LoopStmt.es_Body);
724 ParseWhileStmt(Parse *p, int t, Stmt **pst)
726 Stmt *st = PushStmt(p, pst, ST_Loop, STF_SEMANTIC);
728 t = LexSkipToken(&p->p_Token, TOK_WHILE);
729 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
730 t = ParseExp(p, t, &st->st_LoopStmt.es_BCond);
731 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
732 t = ParseStmt(p, t, &st->st_LoopStmt.es_Body);
738 ParseUntilStmt(Parse *p, int t, Stmt **pst)
740 Stmt *st = PushStmt(p, pst, ST_Loop, STF_SEMANTIC);
742 t = LexSkipToken(&p->p_Token, TOK_WHILE);
743 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
744 t = ParseNotExp(p, t, &st->st_LoopStmt.es_BCond);
745 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
746 t = ParseStmt(p, t, &st->st_LoopStmt.es_Body);
752 ParseDoStmt(Parse *p, int t, Stmt **pst)
754 Stmt *st = PushStmt(p, pst, ST_Loop, STF_SEMANTIC);
756 t = LexSkipToken(&p->p_Token, TOK_DO);
757 t = ParseStmt(p, t, &st->st_LoopStmt.es_Body);
761 t = LexToken(&p->p_Token);
762 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
763 t = ParseExp(p, t, &st->st_LoopStmt.es_ACond);
764 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
765 t = LexSkipToken(&p->p_Token, TOK_SEMI);
768 t = LexToken(&p->p_Token);
769 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
770 t = ParseNotExp(p, t, &st->st_LoopStmt.es_ACond);
771 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
772 t = LexSkipToken(&p->p_Token, TOK_SEMI);
775 t = LexError(&p->p_Token, TOK_ERR_DO_WITHOUT_WHILE);
783 * break [ for | while | do | switch | if | block | <empty> ] ;
784 * continue [ for | while | do | switch | if | block | <empty> ] ;
787 ParseBreakContStmt(Parse *p, int t, Stmt **pst)
789 Stmt *st = PushStmt(p, pst, ST_BreakCont, 0);
794 st->st_BreakStmt.es_IsCont = 1;
797 t = LexToken(&p->p_Token);
800 st->st_BreakStmt.es_StmtType = ST_Case;
801 t = LexToken(&p->p_Token);
804 st->st_BreakStmt.es_StmtType = ST_Loop;
805 t = LexToken(&p->p_Token);
808 st->st_BreakStmt.es_StmtType = ST_Switch;
809 t = LexToken(&p->p_Token);
812 st->st_BreakStmt.es_StmtType = ST_IfElse;
813 t = LexToken(&p->p_Token);
816 st->st_BreakStmt.es_StmtType = ST_Else;
817 t = LexToken(&p->p_Token);
820 st->st_BreakStmt.es_StmtType = ST_Block;
821 t = LexToken(&p->p_Token);
824 /* fall through to semicolon handler */
828 * fall through. If this isn't a ';' we will
835 * Calculate the correct break/continue count.
837 for (scan = st->st_Parent;
838 scan->st_Op != ST_Proc;
839 scan = scan->st_Parent)
841 if (st->st_BreakStmt.es_IsCont) {
842 --st->st_BreakStmt.es_Count;
844 ++st->st_BreakStmt.es_Count;
848 * Stop if we locate the keyword
850 if (st->st_BreakStmt.es_StmtType == scan->st_Op)
854 * if/else has two continue points rather then one, and
855 * 'continue else;' needs to be supported. The first
856 * continue point represents 'continue else', the second
857 * represents 'continue if'.
859 if (st->st_BreakStmt.es_IsCont &&
860 scan->st_Op == ST_IfElse) {
861 if (st->st_BreakStmt.es_StmtType == ST_Else)
863 --st->st_BreakStmt.es_Count;
866 * A standard break breaks out of the nearest loop
867 * or case. A standard continue continues the
870 if (st->st_BreakStmt.es_StmtType == 0) {
871 if (st->st_BreakStmt.es_IsCont) {
872 if (scan->st_Op == ST_Loop)
875 if (scan->st_Op == ST_Switch ||
876 scan->st_Op == ST_Loop)
881 dassert_stmt(st, scan != NULL);
882 if (scan->st_Op == ST_Proc)
883 t = LexError(&p->p_Token, TOK_ERR_BREAK_CONT_NOT_FOUND);
886 t = LexToken(&p->p_Token);
888 t = LexError(&p->p_Token, TOK_ERR_BAD_BREAK_KEYWORD);
891 t = LexError(&p->p_Token, TOK_ERR_SYNTAX);
899 * switch (exp) { cases/default ... }
902 ParseSwitchStmt(Parse *p, int t, Stmt **pst)
904 Stmt *st = PushStmt(p, pst, ST_Switch, 0);
906 t = LexSkipToken(&p->p_Token, TOK_SWITCH);
907 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
908 t = ParseExp(p, t, &st->st_SwStmt.es_Exp);
909 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
910 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
911 while (t == TOK_CASE || t == TOK_DEFAULT) {
912 Stmt *cst = PushStmt(p, NULL, ST_Case, STF_SEMANTIC);
914 t = LexToken(&p->p_Token);
915 t = ParseExp(p, t, &cst->st_CaseStmt.es_Exp);
917 if (st->st_SwStmt.es_Default == NULL) {
918 st->st_SwStmt.es_Default = cst;
919 t = LexToken(&p->p_Token);
921 t = LexError(&p->p_Token,
922 TOK_ERR_MULTIPLE_DEFAULTS);
925 t = LexSkipToken(&p->p_Token, TOK_COLON);
926 while (t != TOK_CASE &&
929 (t & TOKF_ERROR) == 0)
931 t = ParseStmt(p, t, NULL);
935 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
941 ParseThreadSchedStmt(Parse *p, int t, Stmt **pst)
943 Stmt *st = PushStmt(p, pst, ST_ThreadSched, 0);
944 t = LexToken(&p->p_Token);
945 st->st_ThreadSchedStmt.es_Mode = 0;
946 while (t & TOKF_ID) {
947 if (StrCmpToken(String_Preempt, &p->p_Token) == 0) {
948 st->st_ThreadSchedStmt.es_Mode = SPECIAL_AUX_PREEMPT;
949 } else if (StrCmpToken(String_NoPreempt, &p->p_Token) == 0) {
950 st->st_ThreadSchedStmt.es_Mode = SPECIAL_AUX_NOPREEMPT;
951 } else if (StrCmpToken(String_Immediate, &p->p_Token) == 0) {
952 st->st_ThreadSchedStmt.es_Mode = SPECIAL_AUX_IMMEDIATE;
954 t = LexError(&p->p_Token, TOK_ERR_SYNTAX);
956 if ((t & TOKF_ERROR) == 0)
957 t = LexToken(&p->p_Token);
959 t = LexSkipToken(&p->p_Token, TOK_SEMI);
965 * if (exp) stmt [ else stmt ]
968 ParseIfElseStmt(Parse *p, int t, Stmt **pst)
970 Stmt *st = PushStmt(p, pst, ST_IfElse, 0);
972 t = LexSkipToken(&p->p_Token, TOK_IF);
973 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
974 t = ParseExp(p, t, &st->st_IfStmt.es_Exp);
975 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
976 t = ParseStmt(p, t, &st->st_IfStmt.es_TrueStmt);
978 t = LexToken(&p->p_Token);
979 t = ParseStmt(p, t, &st->st_IfStmt.es_FalseStmt);
986 * return ([id:]exp[, [id:]exp]*);
989 ParseReturnStmt(Parse *p, int t, Stmt **pst)
991 Stmt *st = PushStmt(p, pst, ST_Return, 0);
994 t = LexSkipToken(&p->p_Token, TOK_RETURN);
997 t = ParseParenthesizedExp(p, t, &st->st_RetStmt.es_Exp, 1);
998 else if (t != TOK_SEMI)
999 t = ParseExp(p, t, &st->st_RetStmt.es_Exp);
1000 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1003 * Calculate the break-count required to return from the
1004 * procedure. There are no special cases for 'break' count
1008 scan = st->st_Parent;
1009 scan->st_Op != ST_Proc;
1010 scan = scan->st_Parent
1012 ++st->st_RetStmt.es_Count;
1014 ++st->st_RetStmt.es_Count; /* break out of procedure block */
1021 * result ([id:]exp[, [id:]exp]*);
1024 ParseResultStmt(Parse *p, int t, Stmt **pst)
1026 Stmt *st = PushStmt(p, pst, ST_Result, 0);
1030 * Parse a (possibly compound) expression. Note that the parentheses
1033 t = LexSkipToken(&p->p_Token, TOK_RESULT);
1035 if (t == TOK_OPAREN)
1036 t = ParseParenthesizedExp(p, t, &st->st_ResStmt.es_Exp, 1);
1037 else if (t != TOK_SEMI)
1038 t = ParseExp(p, t, &st->st_ResStmt.es_Exp);
1039 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1042 * Calculate the break-count required to return from the
1043 * procedure. There are no special cases for 'break' count
1046 * Note that the compiler and interpreter ignore the break count
1047 * for result() statements.. that is, they do not actually return
1048 * from the procedure from the point of view of the procedure. What
1049 * they do is 'set' the return value and, if the procedure is a thread,
1050 * allow the caller's thread to resume with that value while continuing
1051 * to run the new procedure in its own thread.
1054 scan = st->st_Parent;
1055 scan->st_Op != ST_Proc;
1056 scan = scan->st_Parent
1058 ++st->st_ResStmt.es_Count;
1060 ++st->st_ResStmt.es_Count; /* break out of procedure block */
1067 ParseNopStmt(Parse *p, int t, Stmt **pst)
1069 Stmt *st = PushStmt(p, pst, ST_Nop, 0);
1071 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1077 * A declaration statement, such as: int a = 4, b, c = 27;
1079 * idRequired will either be 1 or 2. 2 is used at the top level of the
1080 * source module, 1 is used elsewhere. Note that if 2 is used the declaration
1081 * may be silently moved out of the current SemGroup and into the SemGroup
1082 * of some other class. Also, an idRequired of 2 implies global scope in the
1083 * case where the declaration is NOT moved. See ParseDeclaration().
1086 ParseDeclarationStmt(Parse *p, int t, int idRequired,
1087 Stmt **pst, int dop, Scope *scope)
1089 Stmt *st = PushStmt(p, pst, ST_Decl, 0);
1091 st->st_DeclStmt.es_Scope = *scope;
1099 t = LexError(&p->p_Token, TOK_ERR_NESTED_CLASS);
1102 case TOK_SUBINTERFACE:
1103 t = LexError(&p->p_Token, TOK_ERR_NESTED_CLASS);
1106 t = ParseDeclaration(p, t, &d, idRequired, dop, scope);
1109 if (st->st_DeclStmt.es_Decl == NULL)
1110 st->st_DeclStmt.es_Decl = d;
1113 * Assign d_Stmt. Force SCOPE_GLOBAL if the declaration
1114 * resides in its import semantic group.
1119 if (d->d_MyGroup == d->d_ImportSemGroup) {
1120 d->d_ScopeFlags |= SCOPE_GLOBAL;
1124 ++st->st_DeclStmt.es_DeclCount;
1129 * Handle a process definition by attaching the { body }.
1131 if (t == TOK_OBRACE) {
1132 if (d->d_Op == DOP_PROC) {
1134 d->d_ProcDecl.ed_Type->ty_Op == TY_PROC);
1135 t = ParseProcStmt(p, t, d,
1136 &d->d_ProcDecl.ed_OrigBody);
1138 t = LexError(&p->p_Token,
1139 TOK_ERR_DECL_NOT_PROCEDURE);
1141 break; /* only one allowed */
1143 if (d->d_Op == DOP_ALIAS) {
1144 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1145 break; /* only one allowed */
1148 * Otherwise look for a comma or a semicolon
1150 if (t == TOK_SEMI) {
1151 t = LexToken(&p->p_Token);
1154 if (t != TOK_COMMA) {
1155 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_COMMA);
1158 t = LexToken(&p->p_Token);
1165 ParseExpStmt(Parse *p, int t, Stmt **pst)
1167 Stmt *st = PushStmt(p, pst, ST_Exp, 0);
1169 t = ParseExp(p, t, &st->st_ExpStmt.es_Exp);
1170 t = LexSkipToken(&p->p_Token, TOK_SEMI);