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 distinguishBlockLabel(Parse *p, int t);
30 static int distinguishDeclaration(Parse *p, int t);
33 * Merge default scope for semantic layer with per-declaration scope.
37 mergeScope(Scope *src, Scope *dst)
39 dst->s_Flags |= src->s_Flags;
40 if (dst->s_AlignOverride == 0)
41 dst->s_AlignOverride = src->s_AlignOverride;
45 * ParseModule() - parse the body of an imported entity.
47 * This function is called from the top level utility to bring in
48 * initial source module, and is called by ParseImport() to import
49 * a new module. We create a placeholder statement to represent
50 * the entire module. Also note that the semantic group will be
51 * associated with the new Parse zone, but is still linked to the
54 * Note that all declarations made at the import level are automatically
58 ParseModule(Parse *p, Stmt *stpar, int t)
62 Scope save_scope = { 0, 0 };
64 dassert_stmt(stpar, stpar->st_Op == ST_Import);
66 st = PushStmt(p, NULL, ST_Module,
67 STF_SEMANTIC | STF_SEMTOP | STF_FORWARD);
68 dassert(stpar->st_Op == ST_Import);
71 * Glue to the parent that imported us. Note that ed_SemGroup will be
72 * NULL for shared-library (.so) imports, since this code is never
73 * reached in that case.
75 stpar->st_ImportStmt.es_SemGroup = st->st_MyGroup;
76 if ((d = stpar->st_ImportStmt.es_Decl) != NULL)
77 d->d_ImportDecl.ed_SemGroup = st->st_MyGroup;
80 if (st->st_LexRef.lr_Lex == NULL)
81 LexInitRef(&st->st_LexRef, &p->p_Token);
83 while ((t & TOKF_ERREOF) == 0) {
86 t = ParseScopeQual(p, t, &scope);
91 t = LexToken(&p->p_Token);
94 scope.s_Flags |= SCOPE_GLOBAL;
95 mergeScope(&save_scope, &scope);
96 t = ParseImportStmt(p, t, &scope);
99 scope.s_Flags |= SCOPE_GLOBAL;
100 scope.s_Flags |= SCOPE_INTERFACE;
103 scope.s_Flags |= SCOPE_GLOBAL;
104 mergeScope(&save_scope, &scope);
105 t = ParseClassStmt(p, t, &scope);
107 case TOK_SUBINTERFACE:
108 scope.s_Flags |= SCOPE_GLOBAL;
109 scope.s_Flags |= SCOPE_INTERFACE;
112 scope.s_Flags |= SCOPE_GLOBAL;
113 mergeScope(&save_scope, &scope);
114 t = ParseSubClassStmt(p, t, &scope);
117 mergeScope(&save_scope, &scope);
118 t = ParseProjectStmt(p, t, &scope);
121 scope.s_Flags |= SCOPE_GLOBAL;
122 mergeScope(&save_scope, &scope);
123 t = ParseTypedefStmt(p, t, &scope);
128 * NOTE: dop is overridden by TOK_ALIAS and other
129 * scope flags such as SCOPE_GLOBAL.
131 * NOTE: We do not set SCOPE_GLOBAL here, because
132 * the declaration might be contextually in
133 * a class (e.g. Fd.setfd). It will be handled
136 mergeScope(&save_scope, &scope);
137 t = ParseDeclarationStmt(p, t, 2, NULL,
138 DOP_GROUP_STORAGE, &scope);
142 if ((t & TOKF_ERROR) == 0)
143 p->p_Format = PFMT_PARSED;
150 ParseStmt(Parse *p, int t, Stmt **pst)
154 t = ParseBlockStmt(p, t, pst);
157 t = ParseForStmt(p, t, pst);
160 t = ParseWhileStmt(p, t, pst);
163 t = ParseUntilStmt(p, t, pst);
166 t = ParseDoStmt(p, t, pst);
170 t = ParseBreakContStmt(p, t, pst);
173 t = ParseSwitchStmt(p, t, pst);
175 case TOK_THREAD_SCHEDULE:
176 t = ParseThreadSchedStmt(p, t, pst);
179 t = ParseIfElseStmt(p, t, pst);
182 t = LexError(&p->p_Token, TOK_ERR_ELSE_WITHOUT_IF);
187 t = ParseReturnStmt(p, t, pst);
190 t = ParseResultStmt(p, t, pst);
193 t = LexError(&p->p_Token, TOK_ERR_CASE_WITHOUT_SWITCH);
198 t = ParseNopStmt(p, t, pst);
201 t = LexError(&p->p_Token, TOK_ERR_DEFAULT_WITHOUT_SWITCH);
207 * Parse a declaration or an expression. Declarations are
208 * distinguished from expressions by beginning with a scope
209 * qualifier, "alias", or a class identifier.
211 if (t == TOK_ID && distinguishBlockLabel(p, t)) {
212 t = ParseBlockStmt(p, t, pst);
213 } else if ((t & (TOKF_STOR_QUAL|TOKF_SCOPE_QUAL)) ||
215 distinguishDeclaration(p, t)
220 * NOTE: TOK_ALIAS will override the passed-in dop
223 t = ParseScopeQual(p, t, &scope);
224 t = ParseDeclarationStmt(p, t, 1, pst,
225 DOP_STACK_STORAGE, &scope);
227 t = ParseExpStmt(p, t, pst);
234 * Return non-zero if the identifier is part of a block label
237 distinguishBlockLabel(Parse *p, int t __unused)
239 token_t tok = p->p_Token;
241 if (LexToken(&tok) == TOK_OBRACE)
248 * Return non-zero to parse as a declaration
251 distinguishDeclaration(Parse *p, int t)
253 token_t tok = p->p_Token;
256 * Possible compound declaration.
258 if (t == TOK_OPAREN) {
260 while (count && ((t = LexToken(&tok)) & TOKF_ERROR) == 0) {
261 /* check comma to detect compound type */
262 if (t == TOK_COMMA && count == 1)
271 } else if ((t & TOKF_ID) == 0) {
276 while ((nt = LexToken(&tok)) == TOK_DOT) {
278 if ((nt & TOKF_ID) == 0)
287 if (t == TOK_CLASSID)
295 if (t == TOK_OPER && tok.t_Ptr[0] == '*')
302 * import "path" [ as id ];
306 ParseImportStmt(Parse *p, int t, Scope *scope)
312 * NOTE: Lexer recognizes that the previous token was TOK_IMPORT
313 * and will parse angle-brackets as if they were quotes.
315 t = LexSkipToken(&p->p_Token, TOK_IMPORT);
319 if (StrCmpToken(String_SelfContained, &p->p_Token) == 0) {
321 while (st->st_Op != ST_Module)
323 if ((st->st_Flags & STF_SELFCONTAINED) == 0) {
324 st->st_Flags |= STF_SELFCONTAINED;
325 st->st_MyGroup->sg_Flags |= SGF_SELFCONTAINED;
327 dassert(st->st_Op == ST_Import);
328 SetSharedImport(&p->p_St,
329 st->st_ImportStmt.es_SemGroup);
331 t = LexToken(&p->p_Token);
332 t = LexSkipToken(&p->p_Token, TOK_SEMI);
334 t = LexError(&p->p_Token, TOK_ERR_SYNTAX);
339 st = PushStmt(p, NULL, ST_Import, STF_SEMANTIC|STF_SEMTOP|STF_FORWARD);
341 st = PushStmt(p, NULL, ST_Import, 0);
343 if (t == TOK_DSTRING)
346 if (t == TOK_DSTRING || t == TOK_ANGLESTR) {
351 LexStripQuotes(&p->p_Token, &tmp);
352 path = StrTableToken(&tmp);
353 if ((ptr = strrchr(path, '/')) != NULL) {
356 &st->st_ImportStmt.es_Path,
362 st->st_ImportStmt.es_File = safe_strdup(ptr);
363 dassert_parse(p, TOK_ERR_EMPTY_PATH, *ptr != 0);
365 st->st_ImportStmt.es_Path = safe_strdup("");
366 st->st_ImportStmt.es_File = safe_strdup(path);
369 t = LexToken(&p->p_Token);
372 st->st_ImportStmt.es_AsId = String_Self;
373 } else if (t == TOK_AS) {
374 t = LexToken(&p->p_Token);
376 st->st_ImportStmt.es_AsId =
377 StrTableToken(&p->p_Token);
378 t = LexToken(&p->p_Token);
380 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_ID);
386 str = StripPathId(st->st_ImportStmt.es_File, &len);
387 st->st_ImportStmt.es_AsId = StrTableAlloc(str, len, 0);
390 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_STRING);
394 * Parse the imported entity (XXX unless shared and already parsed)
396 * NOTE! ParseOpen() is responsible for allocating st_MyGroup
398 if ((t & TOKF_ERROR) == 0) {
402 &st->st_ImportStmt.es_Parser,
403 &st->st_ImportStmt.es_DLL);
404 if (t2 & TOKF_ERROR) {
405 t = LexError(&p->p_Token, t2);
406 } else if (t2 == 0 && (st->st_Flags & STF_SHARED)) {
408 * Assign d_Stmt so a DLL import can find the DLL
409 * (which is stored in the ImportStmt). Note that
410 * ed_SemGroup may be NULL if the import represents
413 * XXX st_MyGroup was overriden, free original?
415 st->st_ImportStmt.es_Decl = AllocImportDecl(st, scope);
416 st->st_ImportStmt.es_Decl->d_ImportDecl.ed_SemGroup =
417 st->st_ImportStmt.es_SemGroup;
418 st->st_ImportStmt.es_Decl->d_Stmt = st;
420 st->st_ImportStmt.es_Decl = AllocImportDecl(st, scope);
421 st->st_ImportStmt.es_Decl->d_Stmt = st;
422 t2 = ParseModule(st->st_ImportStmt.es_Parser, st, t2);
423 if (t2 & TOKF_ERROR) {
425 &st->st_ImportStmt.es_Parser->p_Token);
426 t = LexError(&p->p_Token,
427 TOK_ERR_IMPORT_FAILED);
430 ParseDone(st->st_ImportStmt.es_Parser);
436 t = LexSkipToken(&p->p_Token, TOK_SEMI);
442 * ParseClassStmt() - parse a class or interface.
445 * interface id { ... }
448 ParseClassStmt(Parse *p, int t, Scope *scope)
450 Stmt *st = PushStmt(p, NULL, ST_Class,
451 STF_SEMANTIC | STF_SEMTOP | STF_FORWARD);
454 * Get the dotted id path. Extract the last identifier into id
455 * (it will not be counted by count or appear in the returned array).
457 t = LexSkipToken(&p->p_Token, t); /* class or interface */
458 if (t != TOK_CLASSID) {
459 /*if ((t & TOKF_ID) == 0)*/
460 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_CLASSID);
463 Scope save_scope = { 0, 0 };
465 id = StrTableToken(&p->p_Token); /* retrieve the id */
466 t = LexToken(&p->p_Token);
468 st->st_ClassStmt.es_Decl = AllocClassDecl(st, id, NULL, scope);
469 st->st_ClassStmt.es_Super = NULL;
471 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
472 while ((t & TOKF_ERROR) == 0 && t != TOK_CBRACE) {
475 t = ParseScopeQual(p, t, &scope2);
479 t = LexToken(&p->p_Token);
482 mergeScope(&save_scope, &scope2);
483 t = ParseTypedefStmt(p, t, &scope2);
488 * NOTE: dop is overridden by TOK_ALIAS and
489 * other scope flags such as
492 mergeScope(&save_scope, &scope2);
493 t = ParseDeclarationStmt(p, t, 1, NULL,
499 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
501 if (scope->s_Flags & SCOPE_INTERNAL)
502 t = InternalClassAttach(p, t, st->st_ClassStmt.es_Decl);
510 * ParseSubClassStmt() - parse a subclass or subinterface
512 * subclass id from id[.id]* { ... }
513 * subinterface id from id[.id]* { ... }
516 ParseSubClassStmt(Parse *p, int t, Scope *scope)
518 Stmt *st = PushStmt(p, NULL, ST_Class,
519 STF_SEMANTIC | STF_SEMTOP | STF_FORWARD);
525 t = LexSkipToken(&p->p_Token, t); /* subclass or subinterface */
528 * The subclass identifier. Name of the new subclass
531 id = StrTableToken(&p->p_Token); /* retrieve the id */
532 t = LexToken(&p->p_Token);
534 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_ID);
538 * Get the dotted id path. Extract the last identifier into id
539 * (it will not be counted by count or appear in the returned array).
541 * XXX free ary on error
543 if ((t & TOKF_ERROR) == 0)
544 t = LexSkipToken(&p->p_Token, TOK_FROM);
545 if ((t & TOKF_ERROR) == 0) {
546 t = ParseDotIdAry(p, t, &ary, &count, <);
547 if (lt != TOK_CLASSID)
548 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_CLASSID);
555 * Figure out the superclass, if any.
557 if ((t & TOKF_ERROR) == 0) {
560 Scope save_scope = { 0, 0 };
562 isg = p->p_Import->st_ImportStmt.es_SemGroup;
563 super = AllocUnresolvedType(isg, p->p_CurSemGroup, ary, 1);
565 st->st_ClassStmt.es_Decl = AllocClassDecl(st, id, super, scope);
566 st->st_ClassStmt.es_Super = super;
568 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
569 while ((t & TOKF_ERROR) == 0 && t != TOK_CBRACE) {
572 t = ParseScopeQual(p, t, &scope2);
576 t = LexToken(&p->p_Token);
579 mergeScope(&save_scope, &scope2);
580 t = ParseTypedefStmt(p, t, &scope2);
585 * NOTE: dop is overridden by TOK_ALIAS and
586 * other scope flags such as
589 mergeScope(&save_scope, &scope2);
590 t = ParseDeclarationStmt(p, t, 1, NULL,
596 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
598 if (scope->s_Flags & SCOPE_INTERNAL)
599 t = InternalClassAttach(p, t, st->st_ClassStmt.es_Decl);
606 * ParseProjectStmt() - Set project name for shared persistent variables
609 ParseProjectStmt(Parse *p, int t, Scope *scope __unused)
613 sg = p->p_CurSemGroup;
615 t = LexSkipToken(&p->p_Token, TOK_PROJECT);
616 if (t == TOK_DSTRING) {
619 RelStrTable(&sg->sg_Project);
620 LexStripQuotes(&p->p_Token, &tmp);
621 sg->sg_Project = StrTableToken(&tmp);
622 t = LexToken(&p->p_Token);
624 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_STRING);
626 t = LexSkipToken(&p->p_Token, TOK_SEMI);
631 * ParseTypedefStmt() - parse a typedef
633 * Note that we have to give the typedef global scope so use of the
634 * typedef can occur out of the current context. XXX
637 ParseTypedefStmt(Parse *p, int t, Scope *scope)
639 Stmt *st = PushStmt(p, NULL, ST_Typedef, 0);
641 Scope tscope = *scope;
643 t = LexSkipToken(&p->p_Token, TOK_TYPEDEF);
645 tscope.s_Flags |= SCOPE_GLOBAL;
647 t = ParseDeclaration(p, t, &d, 2, DOP_TYPEDEF, &tscope);
648 if ((t & TOKF_ERROR) == 0) {
649 Type *type = d->d_StorDecl.ed_Type;
650 Exp *exp = d->d_StorDecl.ed_AssExp;
652 d->d_Op = DOP_TYPEDEF;
653 d->d_TypedefDecl.ed_Type = TypeToQualType(type,
657 if (tscope.s_Flags & SCOPE_INTERNAL)
658 InternalTypeAttach(p, t, d);
659 st->st_TypedefStmt.es_Decl = d; /* short cut */
661 t = LexSkipToken(&p->p_Token, TOK_SEMI);
667 ParseBlockStmt(Parse *p, int t, Stmt **pst)
669 Stmt *st = PushStmt(p, pst, ST_Block, STF_SEMANTIC);
672 st->st_BlockStmt.es_BlockId = StrTableToken(&p->p_Token);
673 t = LexSkipToken(&p->p_Token, TOK_ID);
675 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
676 while ((t & TOKF_ERROR) == 0 && t != TOK_CBRACE) {
677 t = ParseStmt(p, t, NULL);
679 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
685 * ParseProcStmt() - process a procedure body
687 * Due to dotted id handling, the current SemGroup may not be
688 * the SemGroup the declaration was placed in. We have to temporarily
689 * switch to the other semgroup in order to process the procedure
692 * If this is a nested procedure we have to mark it as such.
693 * Note that STF_SEMTOP is used for storage management and is
694 * still set for a nested procedure (it's local storage is
695 * independant of its parent).
698 ParseProcStmt(Parse *p, int t, Declaration *d, Stmt **pst)
703 int flags = STF_SEMANTIC|STF_SEMTOP;
705 save = p->p_CurSemGroup;
706 p->p_CurSemGroup = d->d_MyGroup;
708 for (scan = d->d_MyGroup; scan; scan = scan->sg_Parent) {
709 if ((st = scan->sg_Stmt) != NULL && (st->st_Flags & STF_SEMTOP)) {
710 if (st->st_Op == ST_Proc)
716 st = PushStmt(p, pst, ST_Proc, flags);
717 st->st_DeclStmt.es_Decl = d;
718 st->st_DeclStmt.es_DeclCount = 1;
719 st->st_DeclStmt.es_Scope = d->d_Scope;
720 AdjustProcArgsNestingLevel(d, st->st_MyGroup);
722 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
723 while ((t & TOKF_ERROR) == 0 && t != TOK_CBRACE) {
724 t = ParseStmt(p, t, NULL);
726 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
728 p->p_CurSemGroup = save;
734 ParseForStmt(Parse *p, int t, Stmt **pst)
736 Stmt *st = PushStmt(p, pst, ST_Loop, STF_SEMANTIC);
738 t = LexSkipToken(&p->p_Token, TOK_FOR);
739 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
741 /* note: semicolon implied by statement parser */
742 t = ParseStmt(p, t, &st->st_LoopStmt.es_Init);
744 t = ParseExp(p, t, &st->st_LoopStmt.es_BCond);
745 t = LexSkipToken(&p->p_Token, TOK_SEMI);
747 t = ParseExp(p, t, &st->st_LoopStmt.es_AExp);
748 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
749 t = ParseStmt(p, t, &st->st_LoopStmt.es_Body);
755 ParseWhileStmt(Parse *p, int t, Stmt **pst)
757 Stmt *st = PushStmt(p, pst, ST_Loop, STF_SEMANTIC);
759 t = LexSkipToken(&p->p_Token, TOK_WHILE);
760 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
761 t = ParseExp(p, t, &st->st_LoopStmt.es_BCond);
762 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
763 t = ParseStmt(p, t, &st->st_LoopStmt.es_Body);
769 ParseUntilStmt(Parse *p, int t, Stmt **pst)
771 Stmt *st = PushStmt(p, pst, ST_Loop, STF_SEMANTIC);
773 t = LexSkipToken(&p->p_Token, TOK_WHILE);
774 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
775 t = ParseNotExp(p, t, &st->st_LoopStmt.es_BCond);
776 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
777 t = ParseStmt(p, t, &st->st_LoopStmt.es_Body);
783 ParseDoStmt(Parse *p, int t, Stmt **pst)
785 Stmt *st = PushStmt(p, pst, ST_Loop, STF_SEMANTIC);
787 t = LexSkipToken(&p->p_Token, TOK_DO);
788 t = ParseStmt(p, t, &st->st_LoopStmt.es_Body);
792 t = LexToken(&p->p_Token);
793 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
794 t = ParseExp(p, t, &st->st_LoopStmt.es_ACond);
795 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
796 t = LexSkipToken(&p->p_Token, TOK_SEMI);
799 t = LexToken(&p->p_Token);
800 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
801 t = ParseNotExp(p, t, &st->st_LoopStmt.es_ACond);
802 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
803 t = LexSkipToken(&p->p_Token, TOK_SEMI);
806 t = LexError(&p->p_Token, TOK_ERR_DO_WITHOUT_WHILE);
814 * break [ for | while | do | switch | if | block | <empty> ] ;
815 * continue [ for | while | do | switch | if | block | <empty> ] ;
818 ParseBreakContStmt(Parse *p, int t, Stmt **pst)
820 Stmt *st = PushStmt(p, pst, ST_BreakCont, 0);
826 st->st_BreakStmt.es_IsCont = 1;
829 t = LexToken(&p->p_Token);
832 st->st_BreakStmt.es_StmtType = ST_Case;
833 t = LexToken(&p->p_Token);
836 st->st_BreakStmt.es_StmtType = ST_Loop;
837 t = LexToken(&p->p_Token);
840 st->st_BreakStmt.es_StmtType = ST_Switch;
841 t = LexToken(&p->p_Token);
844 st->st_BreakStmt.es_StmtType = ST_IfElse;
845 t = LexToken(&p->p_Token);
848 st->st_BreakStmt.es_StmtType = ST_Else;
849 t = LexToken(&p->p_Token);
852 st->st_BreakStmt.es_StmtType = ST_Block;
853 st->st_BreakStmt.es_BlockId = NULL;
854 t = LexToken(&p->p_Token);
857 id = StrTableToken(&p->p_Token);
858 if (id == String_Procedure) {
859 st->st_BreakStmt.es_StmtType = ST_Proc;
861 st->st_BreakStmt.es_StmtType = ST_Block;
862 st->st_BreakStmt.es_BlockId = id;
864 t = LexToken(&p->p_Token);
867 /* fall through to semicolon handler */
871 * fall through. If this isn't a ';' we will
878 * Calculate the correct break/continue count.
880 for (scan = st->st_Parent;
881 scan->st_Op != ST_Proc;
882 scan = scan->st_Parent)
887 if (st->st_BreakStmt.es_IsCont) {
888 --st->st_BreakStmt.es_Count;
890 ++st->st_BreakStmt.es_Count;
894 * A standard break breaks out of the nearest loop
895 * or case. A standard continue continues the
898 if (st->st_BreakStmt.es_StmtType == 0) {
899 if (st->st_BreakStmt.es_IsCont) {
900 if (scan->st_Op == ST_Loop)
903 if (scan->st_Op == ST_Switch ||
904 scan->st_Op == ST_Loop)
910 * if/else has two continue points. The outer point
911 * is for 'if', the inner point is for else. Both
912 * break points are the same.
914 if (scan->st_Op == ST_IfElse) {
916 * break/continue outer
918 if (st->st_BreakStmt.es_StmtType == ST_IfElse) {
919 if (st->st_BreakStmt.es_IsCont)
920 --st->st_BreakStmt.es_Count;
922 ++st->st_BreakStmt.es_Count;
927 * break/continue inner
929 if (st->st_BreakStmt.es_StmtType == ST_Else)
933 * skip both and continue.
935 if (st->st_BreakStmt.es_IsCont) {
936 --st->st_BreakStmt.es_Count;
938 ++st->st_BreakStmt.es_Count;
943 * Stop if we locate the keyword. If we are breaking
944 * on ST_Block it might be a named block.
946 if (st->st_BreakStmt.es_StmtType == scan->st_Op) {
947 if (scan->st_Op != ST_Block)
949 if (st->st_BreakStmt.es_BlockId == NULL)
951 if (scan->st_BlockStmt.es_BlockId ==
952 st->st_BreakStmt.es_BlockId) {
959 * If we hit the main procedure body top the break/continue
960 * point might not have been found, but we must still check
963 dassert_stmt(st, scan != NULL);
964 if (scan->st_Op == ST_Proc) {
965 if (st->st_BreakStmt.es_StmtType == ST_Proc) {
966 if (st->st_BreakStmt.es_IsCont) {
967 --st->st_BreakStmt.es_Count;
969 ++st->st_BreakStmt.es_Count;
972 t = LexError(&p->p_Token,
973 TOK_ERR_BREAK_CONT_NOT_FOUND);
978 t = LexToken(&p->p_Token);
980 t = LexError(&p->p_Token, TOK_ERR_BAD_BREAK_KEYWORD);
983 t = LexError(&p->p_Token, TOK_ERR_SYNTAX);
991 * switch (exp) { cases/default ... }
994 ParseSwitchStmt(Parse *p, int t, Stmt **pst)
996 Stmt *st = PushStmt(p, pst, ST_Switch, 0);
998 t = LexSkipToken(&p->p_Token, TOK_SWITCH);
999 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
1000 t = ParseExp(p, t, &st->st_SwStmt.es_Exp);
1001 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
1002 t = LexSkipToken(&p->p_Token, TOK_OBRACE);
1003 while (t == TOK_CASE || t == TOK_DEFAULT) {
1004 Stmt *cst = PushStmt(p, NULL, ST_Case, STF_SEMANTIC);
1005 if (t == TOK_CASE) {
1006 t = LexToken(&p->p_Token);
1007 t = ParseExp(p, t, &cst->st_CaseStmt.es_Exp);
1009 if (st->st_SwStmt.es_Default == NULL) {
1010 st->st_SwStmt.es_Default = cst;
1011 t = LexToken(&p->p_Token);
1013 t = LexError(&p->p_Token,
1014 TOK_ERR_MULTIPLE_DEFAULTS);
1017 t = LexSkipToken(&p->p_Token, TOK_COLON);
1018 while (t != TOK_CASE &&
1021 (t & TOKF_ERROR) == 0)
1023 t = ParseStmt(p, t, NULL);
1027 t = LexSkipToken(&p->p_Token, TOK_CBRACE);
1033 ParseThreadSchedStmt(Parse *p, int t, Stmt **pst)
1035 Stmt *st = PushStmt(p, pst, ST_ThreadSched, 0);
1036 t = LexToken(&p->p_Token);
1037 st->st_ThreadSchedStmt.es_Mode = 0;
1038 while (t & TOKF_ID) {
1039 if (StrCmpToken(String_Preempt, &p->p_Token) == 0) {
1040 st->st_ThreadSchedStmt.es_Mode = SPECIAL_AUX_PREEMPT;
1041 } else if (StrCmpToken(String_NoPreempt, &p->p_Token) == 0) {
1042 st->st_ThreadSchedStmt.es_Mode = SPECIAL_AUX_NOPREEMPT;
1043 } else if (StrCmpToken(String_Immediate, &p->p_Token) == 0) {
1044 st->st_ThreadSchedStmt.es_Mode = SPECIAL_AUX_IMMEDIATE;
1046 t = LexError(&p->p_Token, TOK_ERR_SYNTAX);
1048 if ((t & TOKF_ERROR) == 0)
1049 t = LexToken(&p->p_Token);
1051 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1057 * if (exp) stmt [ else stmt ]
1060 ParseIfElseStmt(Parse *p, int t, Stmt **pst)
1062 Stmt *st = PushStmt(p, pst, ST_IfElse, 0);
1064 t = LexSkipToken(&p->p_Token, TOK_IF);
1065 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
1066 t = ParseExp(p, t, &st->st_IfStmt.es_Exp);
1067 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
1068 t = ParseStmt(p, t, &st->st_IfStmt.es_TrueStmt);
1069 if (t == TOK_ELSE) {
1070 t = LexToken(&p->p_Token);
1071 t = ParseStmt(p, t, &st->st_IfStmt.es_FalseStmt);
1078 * return ([id:]exp[, [id:]exp]*);
1081 ParseReturnStmt(Parse *p, int t, Stmt **pst)
1083 Stmt *st = PushStmt(p, pst, ST_Return, 0);
1086 t = LexSkipToken(&p->p_Token, TOK_RETURN);
1088 if (t == TOK_OPAREN)
1089 t = ParseParenthesizedExp(p, t, &st->st_RetStmt.es_Exp, 1);
1090 else if (t != TOK_SEMI)
1091 t = ParseExp(p, t, &st->st_RetStmt.es_Exp);
1092 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1095 * Calculate the break-count required to return from the
1096 * procedure. There are no special cases for 'break' count
1100 scan = st->st_Parent;
1101 scan->st_Op != ST_Proc;
1102 scan = scan->st_Parent
1104 ++st->st_RetStmt.es_Count;
1105 if (scan->st_Op == ST_IfElse) /* if stmt counts twice */
1106 ++st->st_RetStmt.es_Count;
1108 ++st->st_RetStmt.es_Count; /* break out of procedure block */
1115 * result ([id:]exp[, [id:]exp]*);
1118 ParseResultStmt(Parse *p, int t, Stmt **pst)
1120 Stmt *st = PushStmt(p, pst, ST_Result, 0);
1124 * Parse a (possibly compound) expression. Note that the parentheses
1127 t = LexSkipToken(&p->p_Token, TOK_RESULT);
1129 if (t == TOK_OPAREN)
1130 t = ParseParenthesizedExp(p, t, &st->st_ResStmt.es_Exp, 1);
1131 else if (t != TOK_SEMI)
1132 t = ParseExp(p, t, &st->st_ResStmt.es_Exp);
1133 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1136 * Calculate the break-count required to return from the
1137 * procedure. There are no special cases for 'break' count
1140 * Note that the compiler and interpreter ignore the break count
1141 * for result() statements.. that is, they do not actually return
1142 * from the procedure from the point of view of the procedure. What
1143 * they do is 'set' the return value and, if the procedure is a thread,
1144 * allow the caller's thread to resume with that value while continuing
1145 * to run the new procedure in its own thread.
1148 scan = st->st_Parent;
1149 scan->st_Op != ST_Proc;
1150 scan = scan->st_Parent
1152 ++st->st_ResStmt.es_Count;
1153 if (scan->st_Op == ST_IfElse) /* if stmt counts twice */
1154 ++st->st_RetStmt.es_Count;
1156 ++st->st_ResStmt.es_Count; /* break out of procedure block */
1163 ParseNopStmt(Parse *p, int t, Stmt **pst)
1165 Stmt *st = PushStmt(p, pst, ST_Nop, 0);
1167 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1173 * A declaration statement, such as: int a = 4, b, c = 27;
1175 * idRequired will either be 1 or 2. 2 is used at the top level of the
1176 * source module, 1 is used elsewhere. Note that if 2 is used the declaration
1177 * may be silently moved out of the current SemGroup and into the SemGroup
1178 * of some other class. Also, an idRequired of 2 implies global scope in the
1179 * case where the declaration is NOT moved. See ParseDeclaration().
1182 ParseDeclarationStmt(Parse *p, int t, int idRequired,
1183 Stmt **pst, int dop, Scope *scope)
1185 Stmt *st = PushStmt(p, pst, ST_Decl, 0);
1187 st->st_DeclStmt.es_Scope = *scope;
1190 Declaration *d = NULL;
1195 t = LexError(&p->p_Token, TOK_ERR_NESTED_CLASS);
1198 case TOK_SUBINTERFACE:
1199 t = LexError(&p->p_Token, TOK_ERR_NESTED_CLASS);
1202 t = ParseDeclaration(p, t, &d, idRequired, dop, scope);
1205 if (st->st_DeclStmt.es_Decl == NULL)
1206 st->st_DeclStmt.es_Decl = d;
1209 * Assign d_Stmt. Force SCOPE_GLOBAL if the declaration
1210 * resides in its import semantic group.
1215 if (d->d_MyGroup == d->d_ImportSemGroup) {
1216 d->d_ScopeFlags |= SCOPE_GLOBAL;
1220 ++st->st_DeclStmt.es_DeclCount;
1225 * Handle a process definition by attaching the { body }.
1227 if (t == TOK_OBRACE) {
1228 if (d->d_Op == DOP_PROC) {
1230 d->d_ProcDecl.ed_Type->ty_Op == TY_PROC);
1231 t = ParseProcStmt(p, t, d,
1232 &d->d_ProcDecl.ed_OrigBody);
1234 t = LexError(&p->p_Token,
1235 TOK_ERR_DECL_NOT_PROCEDURE);
1237 break; /* only one allowed */
1239 if (d->d_Op == DOP_ALIAS) {
1240 t = LexSkipToken(&p->p_Token, TOK_SEMI);
1241 break; /* only one allowed */
1244 * Otherwise look for a comma or a semicolon
1246 if (t == TOK_SEMI) {
1247 t = LexToken(&p->p_Token);
1250 if (t != TOK_COMMA) {
1251 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_COMMA);
1254 t = LexToken(&p->p_Token);
1261 ParseExpStmt(Parse *p, int t, Stmt **pst)
1263 Stmt *st = PushStmt(p, pst, ST_Exp, 0);
1265 t = ParseExp(p, t, &st->st_ExpStmt.es_Exp);
1266 t = LexSkipToken(&p->p_Token, TOK_SEMI);