Skip to content

Commit 264f3fc

Browse files
committed
[Heavy] Fix generating syntax closures
1 parent 92ab043 commit 264f3fc

File tree

13 files changed

+256
-186
lines changed

13 files changed

+256
-186
lines changed

heavy/include/heavy/Context.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class Context : public ContinuationStack<Context>,
112112
// and swap it back upon completion (via RAII)
113113
// - TODO EnvStack et al. could probably be moved to OpGen.
114114
Value EnvStack;
115+
Environment* GetTopLevelEnvironment(Value Env = nullptr);
116+
void EnsureEnvFrame() {
117+
if (isa<Environment>(EnvStack))
118+
PushEnvFrame();
119+
}
115120

116121
public: // Provide access in lib/Mlir bindings.
117122
std::unique_ptr<mlir::DialectRegistry> DialectRegistry;
@@ -126,6 +131,7 @@ class Context : public ContinuationStack<Context>,
126131
heavy::OpGen* OpGen = nullptr;
127132
heavy::OpEvalPtr OpEval;
128133

134+
129135
// Work around DidCallContinuation being set with compiler errors.
130136
bool CheckError();
131137

@@ -162,7 +168,6 @@ class Context : public ContinuationStack<Context>,
162168
void dumpModuleOp();
163169
void verifyModule();
164170
bool OutputModule(llvm::StringRef MangledName, llvm::StringRef ModulePath);
165-
void PushTopLevel(Value);
166171

167172
// Return true on invalid kind
168173
bool CheckKind(ValueKind VK, Value V);
@@ -181,7 +186,9 @@ class Context : public ContinuationStack<Context>,
181186
EnvStack = E;
182187
}
183188

184-
Environment* getTopLevelEnvironment();
189+
Value& GetLocalEnvStack(Value Stack = nullptr);
190+
// Provide a hashable value for checking for duplicate identifiers.
191+
std::pair<uintptr_t, uintptr_t> GetIdentifierUniqueId(Value V);
185192

186193
Module* RegisterModule(llvm::StringRef MangledName,
187194
heavy::ModuleLoadNamesFn* LoadNames = nullptr);
@@ -225,19 +232,20 @@ class Context : public ContinuationStack<Context>,
225232

226233
// PushEnvFrame - Creates and pushes an EnvFrame to the
227234
// current environment (EnvStack)
228-
EnvFrame* PushEnvFrame(llvm::ArrayRef<Value> Names);
235+
EnvFrame* PushEnvFrame(llvm::ArrayRef<Value> Names = {});
229236
void PopEnvFrame(EnvFrame*);
230237
void PushLocalBinding(Binding* B);
238+
void PushEnv(Value V, Value Env);
231239

232240
// PushLambdaFormals - Check formals, create an EnvFrame,
233241
// and push it onto the EnvStack
234242
// Return the pushed EnvFrame or nullptr.
235-
EnvFrame* PushLambdaFormals(Value Formals, bool& HasRestParam,
236-
SyntaxClosure* SC);
243+
EnvFrame* PushLambdaFormals(Value Formals, bool& HasRestParam);
244+
237245
private:
238246
bool CheckLambdaFormals(Value Formals,
239247
llvm::SmallVectorImpl<Value>& Names,
240-
bool& HasRestParam, SyntaxClosure* SC);
248+
bool& HasRestParam);
241249
public:
242250

243251
void EmitStackSpaceError();

heavy/include/heavy/OpGen.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,7 @@ class OpGen : public ValueVisitor<OpGen, mlir::Value> {
280280
llvm::MutableArrayRef<mlir::Value> Args);
281281
mlir::Value createError(heavy::SourceLocation Loc,
282282
llvm::MutableArrayRef<mlir::Value> Args);
283-
mlir::Value createOpGen(SourceLocation Loc, mlir::Value Input,
284-
mlir::Value Env);
283+
mlir::Value createOpGen(SourceLocation Loc, mlir::Value Input);
285284
mlir::Value createBody(SourceLocation Loc, Value Body);
286285
mlir::Value createSequence(SourceLocation Loc, Value Body);
287286
mlir::Value createSyntaxSpec(Pair* SyntaxSpec, Value OrigCall);
@@ -398,7 +397,7 @@ class OpGen : public ValueVisitor<OpGen, mlir::Value> {
398397

399398
mlir::Value VisitExternName(ExternName* EN);
400399
mlir::Value VisitSyntaxClosure(SyntaxClosure* SC);
401-
mlir::Value VisitSymbol(Symbol* S);
400+
mlir::Value VisitSymbol(Symbol* S, Value ClosedEnv = nullptr);
402401
mlir::Value VisitBinding(Binding* B);
403402

404403
mlir::Value VisitPair(Pair* P);
@@ -410,7 +409,7 @@ class OpGen : public ValueVisitor<OpGen, mlir::Value> {
410409

411410
mlir::Operation* LookupSymbol(llvm::StringRef MangledName);
412411

413-
heavy::EnvEntry LookupEnv(heavy::Value Id);
412+
heavy::EnvEntry LookupEnv(heavy::Value Id, heavy::Value ClosedEnv = nullptr);
414413
private:
415414
mlir::Value CallSyntax(Value Operator, Pair* P);
416415
mlir::Value HandleCall(Pair* P, heavy::EnvEntry FnEnvEntry);

heavy/include/heavy/Ops.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def heavy_OpGenOp : HeavyOp<"opgen", [Terminator]> {
162162
This operation is used for syntax code generation.
163163
}];
164164

165-
let arguments = (ins HeavyValue:$input, HeavyValue:$env);
165+
let arguments = (ins HeavyValue:$input);
166166
let results = (outs);
167167
}
168168

heavy/include/heavy/Value.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,7 @@ class Syntax final
12481248
// transformation.
12491249
// The SourceLocation is the location of the
12501250
// PairWithSource from substitution.
1251+
class EnvFrame;
12511252
class SyntaxClosure : public ValueBase,
12521253
public ValueWithSource {
12531254
public:
@@ -1261,9 +1262,9 @@ class SyntaxClosure : public ValueBase,
12611262
Node(Node)
12621263
{ }
12631264

1264-
// We store one on the stack for lookup.
1265+
// For SC on the stack.
12651266
SyntaxClosure()
1266-
: SyntaxClosure(SourceLocation(), Value(), Value())
1267+
: SyntaxClosure({}, Value(), Value())
12671268
{ }
12681269

12691270
using ValueWithSource::getSourceLocation;
@@ -1281,9 +1282,6 @@ inline bool isIdentifier(Value V) {
12811282
return isa<Symbol>(V);
12821283
}
12831284

1284-
// Provide a hashable value for checking for duplicate identifiers.
1285-
std::pair<uintptr_t, uintptr_t> getIdentifierUniqueId(Value V);
1286-
12871285
class Vector final
12881286
: public ValueBase,
12891287
private llvm::TrailingObjects<Vector, Value> {
@@ -1532,10 +1530,15 @@ class EnvFrame final
15321530
return NumBindings;
15331531
}
15341532

1533+
// Store shadow scopes.
1534+
Value LocalStack;
1535+
15351536
public:
1537+
15361538
EnvFrame(unsigned NumBindings)
15371539
: ValueBase(ValueKind::EnvFrame),
1538-
NumBindings(NumBindings)
1540+
NumBindings(NumBindings),
1541+
LocalStack(Empty())
15391542
{ }
15401543

15411544
llvm::ArrayRef<Binding*> getBindings() const {
@@ -1548,16 +1551,15 @@ class EnvFrame final
15481551
getTrailingObjects<Binding*>(), NumBindings);
15491552
}
15501553

1554+
Value getLocalStack() const { return LocalStack; }
1555+
15511556
static size_t sizeToAlloc(unsigned NumBindings) {
15521557
return totalSizeToAlloc<Binding*>(NumBindings);
15531558
}
15541559

1555-
// Return nullptr if not found.
1556-
EnvEntry Lookup(Value Id) const {
1557-
for (Value V : getBindings()) {
1558-
Binding* B = cast<Binding>(V);
1559-
EnvEntry Result = B->Lookup(Id);
1560-
if (Result)
1560+
EnvEntry LookupBindings(Value Id) const {
1561+
for (Binding* B : getBindings()) {
1562+
if (EnvEntry Result = B->Lookup(Id))
15611563
return Result;
15621564
}
15631565
return {};
@@ -1858,6 +1860,11 @@ inline bool isSymbol(Value V , llvm::StringRef Str) {
18581860
}
18591861
return false;
18601862
}
1863+
inline bool isSymbolAux(Value V , llvm::StringRef Str) {
1864+
if (auto* SC = dyn_cast<SyntaxClosure>(V))
1865+
V = SC->Node;
1866+
return isSymbol(V, Str);
1867+
}
18611868

18621869
inline SourceLocation ValueBase::getSourceLocation() {
18631870
Value Self(this);

0 commit comments

Comments
 (0)