From 0446a338b6633ce3da98613ef43f075f013ab10a Mon Sep 17 00:00:00 2001 From: ivanjermakov Date: Tue, 23 Apr 2024 16:31:46 +0200 Subject: [PATCH] Codegen: complex con patterns --- src/codegen/js/expr.ts | 11 ++++++++--- src/e2e.spec.ts | 19 +++++++++++++++++++ src/semantic/index.ts | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/codegen/js/expr.ts b/src/codegen/js/expr.ts index 4f65d0b9..e46a92d8 100644 --- a/src/codegen/js/expr.ts +++ b/src/codegen/js/expr.ts @@ -402,9 +402,14 @@ export const emitPatternExprCondition = (patternExpr: PatternExpr, ctx: Context, switch (patternExpr.kind) { case 'con-pattern': { const variantName = patternExpr.identifier.names.at(-1)!.value - const cond = `${sVar}.$noisVariant===${jsString(variantName)}` - // TODO: nested patterns - return cond + const conds = [ + `${sVar}.$noisVariant===${jsString(variantName)}`, + ...patternExpr.fieldPatterns.flatMap(f => { + if (!f.pattern) return [] + return [emitPatternExprCondition(f.pattern.expr, ctx, `${sVar}.value.${f.name.value}`)] + }) + ] + return conds.join('&&') } case 'list-pattern': const conds = [ diff --git a/src/e2e.spec.ts b/src/e2e.spec.ts index 8fd64953..9e7dca53 100644 --- a/src/e2e.spec.ts +++ b/src/e2e.spec.ts @@ -350,6 +350,25 @@ pub fn main() { _ { false } } println(a.trace()) +}` + } + const res = run(await compile(files)) + expect(res.stderr.toString()).toEqual('') + expect(res.stdout.toString()).toEqual('true\n') + }) + + it('con-pattern', async () => { + const files = { + 'mod.no': `\ +type Foo { A(), B(b: Int) } +pub fn main() { + let a = match B(6) { + A() { false } + B(b: 5) { false } + B(b) { true } + _ { false } + } + println(a.trace()) }` } const res = run(await compile(files)) diff --git a/src/semantic/index.ts b/src/semantic/index.ts index cc7badfb..5c415bb1 100644 --- a/src/semantic/index.ts +++ b/src/semantic/index.ts @@ -124,7 +124,7 @@ export const checkModule = (module: Module, ctx: Context): void => { } ctx.moduleStack.push(module) - const resolvedRefs = [] + const resolvedRefs: VirtualUseExpr[] = [] for (const useExpr of module.references!) { const ref = checkUseExpr(useExpr, ctx) if (!ref) continue