@@ -45,11 +45,13 @@ clang::SourceLocation getSourceLocation(heavy::FullSourceLocation Loc) {
4545 .getLocWithOffset(Loc.getOffset());
4646}
4747
48- void LoadParentEnv (heavy::HeavyScheme& HS, void * Handle) {
48+ heavy::Environment* LoadEnv (heavy::HeavyScheme& HS, void * Handle) {
4949 DeclContext* DC = reinterpret_cast <DeclContext*>(Handle);
50- if (!DC->isTranslationUnit ()) {
51- HS.LoadEmbeddedEnv (DC->getParent (), LoadParentEnv);
52- }
50+ // Here, nullptr represents the default, root environment.
51+ void * ParentHandle = !DC->isTranslationUnit () ? DC->getParent ()
52+ : nullptr ;
53+
54+ return HS.LoadEmbeddedEnv (ParentHandle, LoadEnv);
5355}
5456
5557// It is complicated to keep the TokenBuffer alive
@@ -154,17 +156,26 @@ bool Parser::ParseHeavyScheme() {
154156 };
155157
156158 auto expr_eval = [&](heavy::Context& C, heavy::ValueRefs Args) {
157- if (Args.size () != 1 ) {
158- C.RaiseError (" invalid arity to function" , C.getCallee ());
159- return ;
159+ heavy::SourceLocation Loc;
160+ heavy::Value Input;
161+ if (Args.size () == 2 ) {
162+ // Accept any value that may have a source location.
163+ Loc = Args[0 ].getSourceLocation ();
164+ Input = Args[1 ];
165+ } else if (Args.size () == 1 ) {
166+ Input = Args[0 ];
167+ } else {
168+ return C.RaiseError (" invalid arity" );
160169 }
161- if (!isa<heavy::String, heavy::Symbol>(Args[ 0 ] )) {
170+ if (!isa<heavy::String, heavy::Symbol>(Input )) {
162171 C.RaiseError (" expecting string or identifier" , C.getCallee ());
163172 return ;
164173 }
165- llvm::StringRef Source = Args[0 ].getStringRef ();
166- heavy::SourceLocation Loc = Args[0 ].getSourceLocation ();
167- if (!Loc.isValid ()) Loc = C.getLoc ();
174+ llvm::StringRef Source = Input.getStringRef ();
175+ if (!Loc.isValid ())
176+ Loc = Input.getSourceLocation ();
177+ if (!Loc.isValid ())
178+ Loc = C.getLoc ();
168179
169180 // Prepare to revert Parser.
170181 TentativeParsingAction ParseReverter (P);
@@ -258,9 +269,11 @@ bool Parser::ParseHeavyScheme() {
258269 ClangLoc, RequestedFilename->getView (),
259270 false , nullptr , nullptr , nullptr , nullptr , nullptr ,
260271 nullptr , nullptr , nullptr );
261- if (!File)
262- return C.RaiseError (" error opening file" ,
263- heavy::Value (RequestedFilename));
272+ if (!File) {
273+ heavy::String* ErrMsg = C.CreateString (" error opening file: " ,
274+ RequestedFilename->getStringRef ());
275+ return C.RaiseError (ErrMsg, heavy::Value (RequestedFilename));
276+ }
264277 // Determine if file is a system file... as if!
265278 SrcMgr::CharacteristicKind FileChar =
266279 this ->PP .getHeaderSearchInfo ()
@@ -308,10 +321,6 @@ bool Parser::ParseHeavyScheme() {
308321
309322 PP.InitEmbeddedLexer (LexerInitFn);
310323
311- // Load the environment for the current DeclContext
312- DeclContext* DC = getActions ().CurContext ;
313- HeavyScheme->LoadEmbeddedEnv (DC, LoadParentEnv);
314-
315324 bool HasError = false ;
316325 auto ErrorHandler = [&](llvm::StringRef Err,
317326 heavy::FullSourceLocation EmbeddedLoc) {
@@ -356,10 +365,13 @@ bool Parser::ParseHeavyScheme() {
356365 C.Cont ();
357366 }));
358367
368+ // Get the nested environment for the current DeclContext.
369+ DeclContext* DC = getActions ().CurContext ;
370+ heavy::Environment* Env = HeavyScheme->LoadEmbeddedEnv (DC, LoadEnv);
371+
359372 heavy::TokenKind Terminator = heavy::tok::r_brace;
360- HeavyScheme->ProcessTopLevelCommands (SchemeLexer,
361- ErrorHandler,
362- Terminator);
373+ HeavyScheme->ProcessTopLevelCommands (SchemeLexer, heavy::base::eval,
374+ ErrorHandler, Env, Terminator);
363375
364376 // Return control to C++ Lexer
365377 PP.FinishEmbeddedLexer (SchemeLexer.GetByteOffset ());
0 commit comments