/* * STMT.H * * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the * COPYRIGHT file at the base of the distribution. */ struct Parse; struct Stmt; typedef runctx_p (*st_run_t)(runctx_p ct, struct Stmt *st); typedef genctx_p (*st_gen_t)(genctx_p ct, struct Stmt *st); /* * Compiler/Interpreter. The return value is designed to allow the * interpreter to deal with break/continue, and even though we do not * have exceptions we can theoretically use it to deal with those too. */ typedef RUNE_HEAD(stmtlist, Stmt) stmtlist_t; typedef struct Stmt { RUNE_ENTRY(Stmt) st_Node; /* node in list */ st_run_t st_Run; /* function vector for interpreter */ st_gen_t st_Gen; /* function vector for generator */ struct Stmt *st_Parent; /* parent statement */ int st_Op; /* ST_ code */ int st_Flags; /* flags */ int st_SaveOffset; /* when saving */ stmtlist_t st_List; /* base of list / parse tree */ SemGroup *st_MyGroup; LexRef st_LexRef; /* for error reporting */ union { struct { struct Parse *es_Parser; /* possibly shared */ string_t es_AsId; /* NULL if self */ Declaration *es_Decl; char *es_Path; char *es_File; SemGroup *es_SemGroup; /* top-level SemGroup */ void *es_DLL; /* DLL */ } ImportStmt; struct { Declaration *es_Decl; Type *es_Super; /* es_Super is same as es_Decl->d_ClassDecl.ed.. */ } ClassStmt; struct { Declaration *es_Decl; } TypedefStmt; /* * NOTE: declarations are stored in their SemGroup's * linked list. The DeclStmt below points into a * subset of this list. */ struct { Declaration *es_Decl; /* first declaration */ int es_DeclCount; /* number of decls */ Scope es_Scope; int es_CallCount; /* heuristic */ runesize_t es_TmpOffset; /* type def init */ } DeclStmt; struct { string_t es_BlockId; } BlockStmt; struct { } NopStmt; struct { } ModuleStmt; struct { struct Stmt *es_Init; Exp *es_BCond; Exp *es_ACond; Exp *es_AExp; struct Stmt *es_Body; } LoopStmt; struct { int es_IsCont; int es_Count; /* +N break, -N cont */ int es_StmtType; string_t es_BlockId; /* if ST_Block only */ } BreakStmt; struct { } BadStmt; struct { Exp *es_Exp; struct Stmt *es_TrueStmt; struct Stmt *es_FalseStmt; } IfStmt; struct { int es_Count; Exp *es_Exp; Type *es_ProcRetType; } RetStmt; struct { int es_Count; Exp *es_Exp; Type *es_ProcRetType; } ResStmt; struct { int es_Mode; } ThreadSchedStmt; struct { Exp *es_Exp; /* switch expression */ struct Stmt *es_Default; /* default statement or NULL */ } SwStmt; struct { Exp *es_Exp; genlabel_t *es_Label; /* (generator only) */ } CaseStmt; struct { Exp *es_Exp; } ExpStmt; } u; } Stmt; #define st_BlockStmt u.BlockStmt #define st_ProcStmt u.DeclStmt #define st_ImportStmt u.ImportStmt #define st_ClassStmt u.ClassStmt #define st_TypedefStmt u.TypedefStmt #define st_DeclStmt u.DeclStmt #define st_NopStmt u.NopStmt #define st_ModuleStmt u.ModuleStmt #define st_LoopStmt u.LoopStmt #define st_BreakStmt u.BreakStmt #define st_BadStmt u.BadStmt #define st_IfStmt u.IfStmt #define st_RetStmt u.RetStmt #define st_ResStmt u.ResStmt #define st_SwStmt u.SwStmt #define st_CaseStmt u.CaseStmt #define st_ExpStmt u.ExpStmt #define st_ThreadSchedStmt u.ThreadSchedStmt #define ST_UNKNOWN 0 /* placemarker for fwd reference */ #define ST_Import 0x0001 /* import statement or top-level file */ #define ST_Class 0x0002 /* class */ #define ST_Typedef 0x0003 /* typedef */ #define ST_Decl 0x0004 /* declaration wrapped by a statement */ #define ST_Block 0x0005 /* braced block */ #define ST_Nop 0x0006 /* empty statement (e.g. just semicolon) */ #define ST_Loop 0x0007 /* for/while/do/until loop */ #define ST_BreakCont 0x0008 /* break or continue */ #define ST_Bad 0x0009 /* bad/illegal statement */ #define ST_IfElse 0x000A /* if or if-else */ #define ST_Return 0x000B /* return from procedure */ #define ST_Result 0x000C /* return value and continue as thread */ #define ST_Switch 0x000D /* switch */ #define ST_Case 0x000E /* case/default in switch */ #define ST_Exp 0x000F /* expression wrapped by a statement */ #define ST_Else 0x0010 /* (synthesized for break/continue) */ #define ST_Proc 0x0011 /* procedure body block statement */ #define ST_ThreadSched 0x0012 /* thread schedule statement */ #define ST_Module 0x0013 /* A module */ /* * STF_SEMANTIC - Indicates that this is a new semantic lavel for * the purposes of a semantic search. * * (ST_Import, ST_Class, ST_Block, ST_Proc, * ST_Loop, ST_Case, ST_Module) * * STF_SEMTOP - ST_Import, ST_Class, ST_Proc, ST_Module * * STF_FORWARD - Indicates that forward references may occur * at this semantic level. This flag is typically * only set in certain non-executable statements. * * STF_NESTED - Indicates that a procedure (ST_Proc) is nested */ #define STF_SEMANTIC 0x0001 /* a semantic rendezvous point */ #define STF_FORWARD 0x0002 /* forward references may occur */ #define STF_TMPRESOLVED 0x0004 /* resolver interlock */ #define STF_RESOLVING 0x0008 /* resolver interlock */ #define STF_RESOLVED 0x0010 /* resolver interlock */ #define STF_MODEXIT 0x0020 /* (import) exit on return */ #define STF_SEMTOP 0x0040 /* top level in semantic group terms */ #define STF_SELFCONTAINED 0x0080 /* (import) self contained */ #define STF_SHARED 0x0100 /* (import) shared import */ #define STF_NESTED 0x0200 /* (proc) nested procedure */ #define STF_COLLAPSING 0x0400 /* collapse pass */ #define STF_COLLAPSED 0x0800 /* collapse pass */ #define STF_ALIGNRESOLVED 0x1000 /* resolver interlock */ #define STF_DIDRESULT 0x2000 /* result stmt encountered */ #define STF_INLINED_PROC 0x4000 /* inined procedure */ #define STF_REFERENCED 0x8000 /* (proc) referenced by resolver */ #define dassert_stmt(stmt, cond) if (!(cond)) StmtFatalError((stmt), 0) #define StmtFatalError(st, type) do { \ LexPrintRef(&(st)->st_LexRef, (type)); \ dpanic(""); \ } while (0)