📄 stu.c
字号:
nwh = FFEINFO_whereNONE; /* DUMMY, INTRINSIC, RESULT. */ ns = FFESYMBOL_stateUNCERTAIN; resolve_intrin = FALSE; } else if (ffeintrin_is_intrinsic (ffesymbol_text (s), NULL, FALSE, &gen, &spec, &imp)) { ffesymbol_signal_change (s); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_generic (s, gen); ffesymbol_set_specific (s, spec); ffesymbol_set_implementation (s, imp); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindNONE, FFEINFO_whereINTRINSIC, FFETARGET_charactersizeNONE)); ffesymbol_resolve_intrin (s); ffesymbol_reference (s, NULL, FALSE); ffestorag_exec_layout (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ return s; } else { /* SPECIAL: can't have CHAR*(*) var in PROGRAM/BLOCKDATA, unless it isn't referenced anywhere in the code. */ ffesymbol_signal_change (s); /* Can't touch this. */ ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_resolve_intrin (s); ffesymbol_reference (s, NULL, FALSE); ffestorag_exec_layout (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ return s; } } else if (sa & FFESYMBOL_attrsTYPE) { assert (!(sa & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsADJUSTS | FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsANYSIZE | FFESYMBOL_attrsARRAY | FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsDUMMY | FFESYMBOL_attrsEQUIV | FFESYMBOL_attrsEXTERNAL | FFESYMBOL_attrsINIT | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsRESULT | FFESYMBOL_attrsSAVE | FFESYMBOL_attrsSFARG | FFESYMBOL_attrsSFUNC))); assert (!(sa & ~(FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsADJUSTS | FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsANYSIZE | FFESYMBOL_attrsARRAY | FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsDUMMY | FFESYMBOL_attrsEQUIV | FFESYMBOL_attrsEXTERNAL | FFESYMBOL_attrsINIT | FFESYMBOL_attrsINTRINSIC /* UNDERSTOOD. */ | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsRESULT | FFESYMBOL_attrsSAVE | FFESYMBOL_attrsSFARG | FFESYMBOL_attrsSFUNC | FFESYMBOL_attrsTYPE))); /* Have it. */ nkd = FFEINFO_kindNONE; /* ENTITY, FUNCTION. */ nwh = FFEINFO_whereNONE; /* DUMMY, GLOBAL, INTRINSIC, LOCAL, RESULT. */ ns = FFESYMBOL_stateUNCERTAIN; resolve_intrin = FALSE; } else if (sa & (FFESYMBOL_attrsCBLOCK | FFESYMBOL_attrsSAVECBLOCK)) { /* COMMON block. */ assert (!(sa & ~(FFESYMBOL_attrsCBLOCK | FFESYMBOL_attrsSAVECBLOCK))); if (sa & FFESYMBOL_attrsCBLOCK) ffebld_end_list (ffesymbol_ptr_to_listbottom (s)); else ffesymbol_set_commonlist (s, NULL); ffestu_list_exec_transition_ (ffesymbol_commonlist (s)); nkd = FFEINFO_kindCOMMON; nwh = FFEINFO_whereLOCAL; needs_type = FALSE; } else { /* First seen in stmt func definition. */ assert (sa == FFESYMBOL_attrsetNONE); assert ("Why are we here again?" == NULL); /* ~~~~~ */ nkd = FFEINFO_kindNONE; /* ENTITY, FUNCTION. */ nwh = FFEINFO_whereNONE; /* DUMMY, GLOBAL, LOCAL. */ ns = FFESYMBOL_stateUNCERTAIN; /* Will get repromoted by caller. */ needs_type = FALSE; } if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, ffesta_tokens[0]); else if (!(na & FFESYMBOL_attrsANY) && (needs_type || (nkd != skd) || (nwh != swh) || (na != sa) || (ns != ss))) { ffesymbol_signal_change (s); ffesymbol_set_attrs (s, na); /* Establish new info. */ ffesymbol_set_state (s, ns); if ((ffesymbol_common (s) == NULL) && (ffesymbol_equiv (s) != NULL)) ffesymbol_set_common (s, ffeequiv_common (ffesymbol_equiv (s))); ffesymbol_set_info (s, ffeinfo_new (ffesymbol_basictype (s), ffesymbol_kindtype (s), ffesymbol_rank (s), nkd, nwh, ffesymbol_size (s))); if (needs_type && !ffeimplic_establish_symbol (s)) ffesymbol_error (s, ffesta_tokens[0]); else if (resolve_intrin) ffesymbol_resolve_intrin (s); ffesymbol_reference (s, NULL, FALSE); ffestorag_exec_layout (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ } return s;}/* ffestu_list_exec_transition_ -- Update SYMTERs in ITEM list w/in symbol ffebld list; ffestu_list_exec_transition_(list); list contains an FFEBLD_opITEM list of SYMTERs (possibly STARs and other things, too, but we'll ignore the known ones). For each SYMTER, we run sym_exec_transition_ on the corresponding ffesymbol (a recursive call, since that's the function that's calling us) to update it's information. Then we copy that information into the SYMTER. Make sure we don't get called recursively ourselves! */static voidffestu_list_exec_transition_ (ffebld list){ static bool in_progress = FALSE; ffebld item; ffesymbol symbol; assert (!in_progress); in_progress = TRUE; for (; list != NULL; list = ffebld_trail (list)) { if ((item = ffebld_head (list)) == NULL) continue; /* Try next item. */ switch (ffebld_op (item)) { case FFEBLD_opSTAR: break; case FFEBLD_opSYMTER: symbol = ffebld_symter (item); if (symbol == NULL) break; /* Detached from stmt func dummy list. */ symbol = ffecom_sym_exec_transition (symbol); assert (ffesymbol_kind (symbol) != FFEINFO_kindNONE); assert (ffesymbol_where (symbol) != FFEINFO_whereNONE); ffebld_set_info (item, ffesymbol_info (symbol)); break; default: assert ("Unexpected item on list" == NULL); break; } } in_progress = FALSE;}/* ffestu_symter_end_transition_ -- Update SYMTERs in expr w/in symbol ffebld expr; ffestu_symter_end_transition_(expr); Any SYMTER in expr's tree with whereNONE gets updated to the (recursively transitioned) sym it identifies (DUMMY or COMMON). */static boolffestu_symter_end_transition_ (ffebld expr){ ffesymbol symbol; bool any = FALSE; /* Label used for tail recursion (reset expr and go here instead of calling self). */tail: /* :::::::::::::::::::: */ if (expr == NULL) return any; switch (ffebld_op (expr)) { case FFEBLD_opITEM: while (ffebld_trail (expr) != NULL) { if (ffestu_symter_end_transition_ (ffebld_head (expr))) any = TRUE; expr = ffebld_trail (expr); } expr = ffebld_head (expr); goto tail; /* :::::::::::::::::::: */ case FFEBLD_opSYMTER: symbol = ffecom_sym_end_transition (ffebld_symter (expr)); if ((symbol != NULL) && ffesymbol_attr (symbol, FFESYMBOL_attrANY)) any = TRUE; ffebld_set_info (expr, ffesymbol_info (symbol)); break; case FFEBLD_opANY: return TRUE; default: break; } switch (ffebld_arity (expr)) { case 2: if (ffestu_symter_end_transition_ (ffebld_left (expr))) any = TRUE; expr = ffebld_right (expr); goto tail; /* :::::::::::::::::::: */ case 1: expr = ffebld_left (expr); goto tail; /* :::::::::::::::::::: */ default: break; } return any;}/* ffestu_symter_exec_transition_ -- Update SYMTERs in expr w/in symbol ffebld expr; ffestu_symter_exec_transition_(expr); Any SYMTER in expr's tree with whereNONE gets updated to the (recursively transitioned) sym it identifies (DUMMY or COMMON). */static boolffestu_symter_exec_transition_ (ffebld expr){ ffesymbol symbol; bool any = FALSE; /* Label used for tail recursion (reset expr and go here instead of calling self). */tail: /* :::::::::::::::::::: */ if (expr == NULL) return any; switch (ffebld_op (expr)) { case FFEBLD_opITEM: while (ffebld_trail (expr) != NULL) { if (ffestu_symter_exec_transition_ (ffebld_head (expr))) any = TRUE; expr = ffebld_trail (expr); } expr = ffebld_head (expr); goto tail; /* :::::::::::::::::::: */ case FFEBLD_opSYMTER: symbol = ffecom_sym_exec_transition (ffebld_symter (expr)); if ((symbol != NULL) && ffesymbol_attr (symbol, FFESYMBOL_attrANY)) any = TRUE; ffebld_set_info (expr, ffesymbol_info (symbol)); break; case FFEBLD_opANY: return TRUE; default: break; } switch (ffebld_arity (expr)) { case 2: if (ffestu_symter_exec_transition_ (ffebld_left (expr))) any = TRUE; expr = ffebld_right (expr); goto tail; /* :::::::::::::::::::: */ case 1: expr = ffebld_left (expr); goto tail; /* :::::::::::::::::::: */ default: break; } return any;}/* ffestu_dummies_transition_ -- Update SYMTERs in ITEM list w/in entry ffebld list; ffesymbol symfunc(ffesymbol s); if (ffestu_dummies_transition_(symfunc,list)) // One or more items are still UNCERTAIN. list contains an FFEBLD_opITEM list of SYMTERs (possibly STARs and other things, too, but we'll ignore the known ones). For each SYMTER, we run symfunc on the corresponding ffesymbol (a recursive call, since that's the function that's calling us) to update it's information. Then we copy that information into the SYMTER. Return TRUE if any of the SYMTER's has incomplete information. Make sure we don't get called recursively ourselves! */static boolffestu_dummies_transition_ (ffesymbol (*symfunc) (ffesymbol), ffebld list){ static bool in_progress = FALSE; ffebld item; ffesymbol symbol; bool uncertain = FALSE; assert (!in_progress); in_progress = TRUE; for (; list != NULL; list = ffebld_trail (list)) { if ((item = ffebld_head (list)) == NULL) continue; /* Try next item. */ switch (ffebld_op (item)) { case FFEBLD_opSTAR: break; case FFEBLD_opSYMTER: symbol = ffebld_symter (item); if (symbol == NULL) break; /* Detached from stmt func dummy list. */ symbol = (*symfunc) (symbol); if (ffesymbol_state (symbol) == FFESYMBOL_stateUNCERTAIN) uncertain = TRUE; else { assert (ffesymbol_kind (symbol) != FFEINFO_kindNONE); assert (ffesymbol_where (symbol) != FFEINFO_whereNONE); } ffebld_set_info (item, ffesymbol_info (symbol)); break; default: assert ("Unexpected item on list" == NULL); break; } } in_progress = FALSE; return uncertain;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -