#include <assert.h>#include <stdint.h>#include <stdlib.h>#include <dirent.h>#include <fstream>#include <iostream>#include <string>#include <stack>#include "Options.hxx"#include "AST.hxx"#include "Environment.hxx"#include "Symtab.hxx"#include "inter-pass.hxx"#include "MixFix.hxx"Go to the source code of this file.
Defines | |
| #define | REWRITE_AST_IN_PLACE(_to, _from) |
| #define | RESOLVE(ast, env, lamLevel, mode, identType, currLB, flags) |
Functions | |
| static bool | warnUnresRef (std::ostream &errStream, shared_ptr< AST > mod, shared_ptr< ASTEnvironment > env) |
| static shared_ptr< UocInfo > | findInterface (std::ostream &errStream, shared_ptr< AST > ifAst) |
| static void | aliasPublicBindings (const std::string &idName, shared_ptr< ASTEnvironment > aliasEnv, shared_ptr< ASTEnvironment > fromEnv, shared_ptr< ASTEnvironment > toEnv) |
| static bool | importIfBinding (std::ostream &errStream, shared_ptr< ASTEnvironment > aliasEnv, shared_ptr< AST > ifName) |
| static bool | providing (shared_ptr< ASTEnvironment > aliasEnv, const FQName &fqn) |
| static void | bindIdentDef (shared_ptr< AST > ast, shared_ptr< ASTEnvironment > env, IdentType identType, shared_ptr< AST > currLB, ResolverFlags rflags) |
| static void | markComplete (shared_ptr< ASTEnvironment > env) |
| bool | resolve (std::ostream &errStream, shared_ptr< AST > ast, shared_ptr< ASTEnvironment > aliasEnv, shared_ptr< ASTEnvironment > env, shared_ptr< ASTEnvironment > lamLevel, ResolutionMode mode, IdentType identType, shared_ptr< AST > currLB, ResolverFlags flags) |
| The symbol resolver. | |
| static bool | initEnv (std::ostream &errStream, shared_ptr< AST > ast, shared_ptr< ASTEnvironment > aliasEnv, shared_ptr< ASTEnvironment > env) |
| #define REWRITE_AST_IN_PLACE | ( | _to, | |||
| _from | ) |
Value:
do { \ shared_ptr<AST> to = (_to); \ shared_ptr<AST> from = (_from); \ \ to->s = from->s; \ to->astType = from->astType; \ to->identType = from->identType; \ to->flags = from->flags; \ to->children = from->children; \ to->fqn = from->fqn; \ } while (0)
Definition at line 384 of file Symtab.cxx.
Referenced by resolve().
| static void aliasPublicBindings | ( | const std::string & | idName, | |
| shared_ptr< ASTEnvironment > | aliasEnv, | |||
| shared_ptr< ASTEnvironment > | fromEnv, | |||
| shared_ptr< ASTEnvironment > | toEnv | |||
| ) | [static] |
Definition at line 201 of file Symtab.cxx.
References BF_COMPLETE, BF_PRIVATE, if(), FQName::LocalBindingSep, and s.
| static void bindIdentDef | ( | shared_ptr< AST > | ast, | |
| shared_ptr< ASTEnvironment > | env, | |||
| IdentType | identType, | |||
| shared_ptr< AST > | currLB, | |||
| ResolverFlags | rflags | |||
| ) | [static] |
Definition at line 344 of file Symtab.cxx.
References assert(), BF_COMPLETE, BF_NO_MERGE, id_tvar, and id_unresolved.
| static shared_ptr<UocInfo> findInterface | ( | std::ostream & | errStream, | |
| shared_ptr< AST > | ifAst | |||
| ) | [static] |
Definition at line 141 of file Symtab.cxx.
References boost::GC_NULL, and UocInfo::ifList.
Referenced by importIfBinding().
| static bool importIfBinding | ( | std::ostream & | errStream, | |
| shared_ptr< ASTEnvironment > | aliasEnv, | |||
| shared_ptr< AST > | ifName | |||
| ) | [static] |
Definition at line 249 of file Symtab.cxx.
References BF_PRIVATE, findInterface(), if(), Environment< T >::make(), and s.
Referenced by resolve().
| static bool initEnv | ( | std::ostream & | errStream, | |
| shared_ptr< AST > | ast, | |||
| shared_ptr< ASTEnvironment > | aliasEnv, | |||
| shared_ptr< ASTEnvironment > | env | |||
| ) | [static] |
Definition at line 2834 of file Symtab.cxx.
References aliasPublicBindings(), at_interface, boost::GC_NULL, and UocInfo::ifList.
Referenced by UocInfo::DoResolve().
| static void markComplete | ( | shared_ptr< ASTEnvironment > | env | ) | [static] |
| static bool providing | ( | shared_ptr< ASTEnvironment > | aliasEnv, | |
| const FQName & | fqn | |||
| ) | [static] |
Definition at line 295 of file Symtab.cxx.
References assert(), BF_PROVIDING, FQName::ident, and FQName::iface.
Referenced by resolve().
| bool resolve | ( | std::ostream & | errStream, | |
| shared_ptr< AST > | ast, | |||
| shared_ptr< ASTEnvironment > | aliasEnv, | |||
| shared_ptr< ASTEnvironment > | env, | |||
| shared_ptr< ASTEnvironment > | lamLevel, | |||
| ResolutionMode | mode, | |||
| IdentType | identType, | |||
| shared_ptr< AST > | currLB, | |||
| ResolverFlags | flags | |||
| ) |
The symbol resolver.
Traverses ast, keeping track of the current environment env, the alias environment aliasEnv, the environment lamLevel that was in effect at the most recently enclosing lambda form, and a pointer to the AST of the most recently enclosing let binding form.
The mode determines whether we are defining, declaring, or using identifiers at any given moment (see ResolutionMode). In DEF_MODE and DECL_MODE, identifiers will be added to the current environment. In USE_MODE, identifiers will be looked up.
LOCAL_MODE AND TYPE_MODE are not used by the resolver.
Various context-dependent constraints on the resolver are dictated by flags (see ResolverFlags).
The expected/required identifier classification is carried downward through identType. In DEF_MODE, identType specifies the identifier class to be defined. In USE_MODE, it specifies the type of identifier that may legally occur. WHAT ABOUT IN DECL_MODE?
Hygienic symbols are decidedly odd. Syntactically they look like structure references, but the LHS is actually a local identifier that names an environment. More precisely, it names a local copy of the imported interface's environment that contains only the public symbols of that interface.
We handle this through an outright kludge. At the point of hygienic import, we bind both the ifalias (for uniqueness) and all of the imported identifiers. The imported identifiers get bound in the local namespace using "ifalias.ifident" (note that '.' is not a legal identifier character, so this cannot be matched otherwise).
At defining and use occurrences, we recognize the selector pattern in the parser and generate an at_usesel AST node for it. We then arrive here, where we re-write the at_usesel node IN PLACE, rewriting it into an at_ident node whose name is "ifalias.ident", where "ifalias" is our local name for the interface's public environment. We then recurse by hand on the same node** (the one that we just re-wrote) to get the symbol resolved.
The only problem with that is that the recursive resolution is going to give us an FQN whose iface component is the current UoC and whose ident component is our forged "ifalias.ident". Ultimately, the at_usesel is actually an alias of the other symbol, so its FQN needs to be the FQN of the external symbol. We ensure this by whacking it back to the right thing after the hand-recursing resolution returns.
Finally, note that BeginSimp has done a rewrite of all local at_define and at_recdef forms into at_let and at_letrec forms, respectively. That pass has checked that no at_usesel can be bound by a local definition. I do wonder if perhaps we should not catch this case syntactically in the parser.
neither case is currently handled, and both need to be. It may turn out to be better to handle this case specially.
Note that BeginSimp has re-written all local define and recdef forms into at_let and at_letrec, respectively, so if we see at_define or at_refdef here, it is a top-level form.
If the type class is marked ":closed", then it is required that all instance definitions appear in the same interface or module as the type class definition.
The exception to this is that certain constraints that are incestuously known to the compiler are defined in the prelude as :closed but are extended at need by the implementation. Examples of this include
Definition at line 433 of file Symtab.cxx.
References agt_category, agt_CompilationUnit, agt_definition, agt_eform, agt_expr, agt_expr_or_define, agt_fielditem, agt_if_definition, agt_literal, agt_openclosed, agt_ow, agt_qtype, agt_tc_definition, agt_tvar, agt_type, agt_type_definition, agt_ucon, agt_uselhs, agt_value_definition, agt_var, aliasPublicBindings(), argVec, assert(), at_allocREF, at_and, at_AnyGroup, at_apply, at_argVec, at_array, at_array_nth, at_array_ref_nth, at_arrayRefType, at_arrayType, at_begin, at_bitfieldType, at_bitsizeof, at_boolLiteral, at_boxedCat, at_boxedType, at_byRefType, at_charLiteral, at_cond, at_cond_leg, at_cond_legs, at_condelse, at_constraints, at_constructor, at_constructors, at_constType, at_container, at_copyREF, at_declare, at_declares, at_declrepr, at_declstruct, at_declunion, at_defexception, at_define, at_definstance, at_defobject, at_defrepr, at_defstruct, at_deftypeclass, at_defunion, at_deref, at_docString, at_dummyType, at_dup, at_exceptionType, at_field, at_fields, at_fieldType, at_fill, at_floatLiteral, at_fn, at_fnargVec, at_fqCtr, at_frameBindings, at_ident, at_identList, at_identPattern, at_if, at_ifident, at_ifsel, at_import, at_importAs, at_inner_ref, at_interface, at_intLiteral, at_labeledBlock, at_lambda, at_let, at_letbinding, at_letbindings, at_letGather, at_letrec, at_letStar, at_localFrame, at_loop, at_loopbinding, at_loopbindings, at_looptest, at_MakeVector, at_methdecl, at_method_decl, at_method_decls, at_methType, at_mixfix, at_mkArrayRef, at_mkClosure, at_module, at_mutableType, at_nth, at_Null, at_object_apply, at_oc_closed, at_oc_open, at_opaqueCat, at_or, at_otherwise, at_primaryType, at_proclaim, at_provide, at_qualType, at_recdef, at_reprctr, at_reprctrs, at_reprrepr, at_return_from, at_sel_ctr, at_select, at_setbang, at_setClosure, at_sizeof, at_stringLiteral, at_struct_apply, at_suspend, at_tcapp, at_tcdecls, at_tcmethod_binding, at_tcmethods, at_throw, at_try, at_tvlist, at_tyfn, at_typeAnnotation, at_typeapp, at_ucon_apply, at_unboxedCat, at_unboxedType, at_unit, at_unless, at_usesel, at_usw_leg, at_usw_legs, at_uswitch, at_vector, at_vector_nth, at_vectorType, at_when, BF_COMPLETE, BF_PRIVATE, BF_PROVIDING, bindIdentDef(), CHKERR, DECL_MODE, DEF_IS_EXTERNAL, DEF_MODE, flags, FQ_NOIF, boost::GC_NULL, id_block, id_field, ID_FOR_USWITCH, id_interface, ID_IS_GLOBAL, ID_IS_MUTATED, ID_IS_PRIVATE, ID_MUT_CLOSED, id_object, id_struct, id_tcmethod, id_tvar, id_typeclass, id_ucon, id_ucon0, id_union, id_unresolved, id_value, idc_apply, idc_type, idc_uctor, idc_usesel_lhs, idc_value, identTypeToString(), importIfBinding(), INNER_REF_NDX, LB_REC_BIND, lbs, LBS_PROCESSED, FQName::LocalBindingSep, AST::make(), markComplete(), MASK_FLAGS_FROM_USE, NULL_MODE, ProcessMixFix(), providing(), RESOLVE, REWRITE_AST_IN_PLACE, RSLV_BIND_PUBLIC, RSLV_INCOMPLETE_NO_CHK, RSLV_INCOMPLETE_OK, RSLV_IS_INTERFACE, RSLV_NEW_TV_OK, RSLV_NO_CHK_USE_TYPE, RSLV_NO_RESOLVE_DECL, RSLV_SWITCHED_ID_OK, RSLV_USE_ONLY_PUBLIC, RSLV_WITHIN_CATCH, RSLV_WITHIN_CATCH_MC, RSLV_WITHIN_DEFUNION, TVAR_POLY_SPECIAL, USE_MODE, and warnUnresRef().
Referenced by UocInfo::DoResolve().
| static bool warnUnresRef | ( | std::ostream & | errStream, | |
| shared_ptr< AST > | mod, | |||
| shared_ptr< ASTEnvironment > | env | |||
| ) | [static] |
Definition at line 91 of file Symtab.cxx.
References assert(), at_declstruct, at_declunion, at_module, at_proclaim, DEF_IS_EXTERNAL, PROCLAIM_IS_INTERNAL, and Options::Wall.
Referenced by resolve().
1.4.7