add case extraction variables to locals

This commit is contained in:
2023-02-20 06:13:26 -07:00
parent b2eab150f2
commit 0641ec8b37
2 changed files with 44 additions and 7 deletions

View File

@@ -252,6 +252,7 @@ class Helpers {
var expNames = []; var expNames = [];
var listVarSymbol = null; var listVarSymbol = null;
var varsInScope:Array<Var> = [];
function makeSwitchPattern(patternExp:ReaderExp):Array<Expr> { function makeSwitchPattern(patternExp:ReaderExp):Array<Expr> {
return switch (patternExp.def) { return switch (patternExp.def) {
case CallExp({pos: _, def: Symbol("when")}, whenExps): case CallExp({pos: _, def: Symbol("when")}, whenExps):
@@ -276,17 +277,17 @@ class Helpers {
expNames.push(exp); expNames.push(exp);
case ListRestExp(name): case ListRestExp(name):
if (restExpIndex > -1) { if (restExpIndex > -1) {
throw KissError.fromExp(patternExp, "list-eating pattern cannot have multiple ... or ...[restVar] expressions"); throw KissError.fromExp(patternExp, "list-eating pattern cannot have multiple ... or ...<restVar> expressions");
} }
restExpIndex = idx; restExpIndex = idx;
restExpName = name; restExpName = name;
default: default:
throw KissError.fromExp(exp, "list-eating pattern can only contain symbols, ..., or ...[restVar]"); throw KissError.fromExp(exp, "list-eating pattern can only contain symbols, ..., or ...<restVar>");
} }
} }
if (restExpIndex == -1) { if (restExpIndex == -1) {
throw KissError.fromExp(patternExp, "list-eating pattern is missing ... or ...[restVar]"); throw KissError.fromExp(patternExp, "list-eating pattern is missing ... or ...<restVar>");
} }
if (expNames.length == 0) { if (expNames.length == 0) {
@@ -298,7 +299,21 @@ class Helpers {
guard = k.convert(b.callSymbol(">", [b.field("length", listVarSymbol), b.raw(Std.string(expNames.length))])); guard = k.convert(b.callSymbol(">", [b.field("length", listVarSymbol), b.raw(Std.string(expNames.length))]));
makeSwitchPattern(listVarSymbol); makeSwitchPattern(listVarSymbol);
default: default:
[k.forCaseParsing().convert(patternExp)]; var patternExpr = k.forCaseParsing().convert(patternExp);
// Recurse into the pattern expr for identifiers that must be added
// to vars in scope:
function findIdents(subExpr) {
switch (subExpr.expr) {
case EConst(CIdent(name)):
varsInScope.push({name: name});
default:
haxe.macro.ExprTools.iter(subExpr, findIdents);
}
}
findIdents(patternExpr);
[patternExpr];
} }
} }
@@ -307,7 +322,14 @@ class Helpers {
var pattern = makeSwitchPattern(patternExp); var pattern = makeSwitchPattern(patternExp);
var b = caseExp.expBuilder(); var b = caseExp.expBuilder();
var body = if (restExpIndex == -1) { var body = if (restExpIndex == -1) {
k.convert(b.begin(caseBodyExps)); for (v in varsInScope) {
k.addVarInScope(v, true, false);
}
var e = k.convert(b.begin(caseBodyExps));
for (v in varsInScope) {
k.removeVarInScope(v, true);
}
e;
} else { } else {
var letBindings = []; var letBindings = [];
for (idx in 0...restExpIndex) { for (idx in 0...restExpIndex) {

View File

@@ -851,8 +851,23 @@ From:[(assert false (+ \"false \" \"should \" \"have \" \"been \" \"true\"))]" m
(Assert.isTrue (savedPrints.contains "s: null")) (Assert.isTrue (savedPrints.contains "s: null"))
(Assert.equals 5 savedPrints.length) (Assert.equals 5 savedPrints.length)
// TODO test case extraction locals: // Test case extraction locals:
)) (set savedPrints [])
(case None
(None (printLocalNulls) /* Won't print */)
(otherwise))
(case (Some null)
((Some v) (printLocalNulls))
(otherwise))
(Assert.isTrue (savedPrints.contains "v: null"))
(Assert.equals 1 savedPrints.length)
(set savedPrints [])
(case (Some (Some (Some [1 2 null])))
((Some (Some (Some [a b c])))
(printLocalNulls))
(otherwise))
(Assert.isTrue (savedPrints.contains "c: null"))))
(function :Void _testTypeCase [] (function :Void _testTypeCase []
(typeCase ["a"] (typeCase ["a"]