From 27b37341e5efc3d3a465a8d16962bd8d9aa62760 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Tue, 10 Jan 2023 11:05:32 -0800 Subject: [PATCH] Playground uses run() to automatically sync w compiler passes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes playground to use the modified `run()` function of the compiler, polling the generator and building up a Map of tabs automatically based on the passes that the compiler runs. This means tabs are always derived from the current state of the compiler and we can never forget to add a pass. Screen Shot 2023-01-10 at 11 06 03 AM Note the inclusion of some recently added passes that weren't added to the playground — which was my fault but only bc i intended to ship this PR soon :-) --- .../playground/components/Editor/Output.tsx | 256 ++++++------------ .../playground/components/Editor/index.tsx | 10 +- .../playground/components/TabbedWindow.tsx | 44 ++- 3 files changed, 106 insertions(+), 204 deletions(-) diff --git a/compiler/forget/packages/playground/components/Editor/Output.tsx b/compiler/forget/packages/playground/components/Editor/Output.tsx index 07ddfe04cf..59671f872d 100644 --- a/compiler/forget/packages/playground/components/Editor/Output.tsx +++ b/compiler/forget/packages/playground/components/Editor/Output.tsx @@ -9,59 +9,22 @@ import MonacoEditor from "@monaco-editor/react"; import { HIR } from "babel-plugin-react-forget"; import prettier from "prettier"; import prettierParserBabel from "prettier/parser-babel"; -import { memo, useMemo } from "react"; +import { memo, useMemo, useState } from "react"; import type { Store } from "../../lib/stores"; -import TabbedWindow, { TabTypes } from "../TabbedWindow"; +import TabbedWindow from "../TabbedWindow"; import { monacoOptions } from "./monacoOptions"; -const { - buildReactiveFunction, - codegenReactiveFunction, - eliminateRedundantPhi, - enterSSA, - Environment, - flattenReactiveLoops, - inferTypes, - inferMutableRanges, - inferReactiveScopes, - inferReactiveScopeVariables, - inferReferenceEffects, - leaveSSA, - lower, - parseFunctions, - printHIR, - printReactiveFunction, - propagateScopeDependencies, - pruneUnusedLabels, - pruneUnusedScopes, -} = HIR; +const { parseFunctions, printHIR, printReactiveFunction } = HIR; const MemoizedOutput = memo(Output); export default MemoizedOutput; type Props = { store: Store; - tabsOpen: Map; - setTabsOpen: (newTab: Map) => void; -}; - -type CompilerOutput = { - ssaOutput: string; - hirOutput: string; - eliminateRedundantPhiOutput: string; - inferTypesOutput: string; - inferReferenceEffectsOutput: string; - inferMutableRangesOutput: string; - inferReactiveScopeVariablesOutput: string; - inferReactiveScopesOutput: string; - reactiveFunctionOutput: string; - leaveSSAOutput: string; - codegenOutput: string; - sourceMapUrl: string | null; }; type CompilerError = string; -function compile(source: string): CompilerOutput | CompilerError { +function compile(source: string): Map | CompilerError { try { const astFunctions = parseFunctions(source); if (astFunctions.length === 0) { @@ -70,82 +33,96 @@ function compile(source: string): CompilerOutput | CompilerError { // TODO: Handle multiple functions const func = astFunctions[0]; - const env = new Environment(); - const ir = lower(func, env); - const hirOutput = printHIR(ir.body); - - enterSSA(ir, env); - const ssaOutput = printHIR(ir.body); - - eliminateRedundantPhi(ir); - const eliminateRedundantPhiOutput = printHIR(ir.body); - - inferTypes(ir); - const inferTypesOutput = printHIR(ir.body); - - inferReferenceEffects(ir); - const inferReferenceEffectsOutput = printHIR(ir.body); - - inferMutableRanges(ir); - const inferMutableRangesOutput = printHIR(ir.body); - - leaveSSA(ir); - const leaveSSAOutput = printHIR(ir.body); - - inferReactiveScopeVariables(ir); - const inferReactiveScopeVariablesOutput = printHIR(ir.body); - - inferReactiveScopes(ir); - const inferReactiveScopesOutput = printHIR(ir.body); - - const reactiveFunction = buildReactiveFunction(ir); - pruneUnusedLabels(reactiveFunction); - flattenReactiveLoops(reactiveFunction); - propagateScopeDependencies(reactiveFunction); - pruneUnusedScopes(reactiveFunction); - const reactiveFunctionOutput = printReactiveFunction(reactiveFunction); - - const ast = codegenReactiveFunction(reactiveFunction); - const generated = generate( - ast, - { - sourceMaps: true, - sourceFileName: "input.js", - }, - source - ); - const sourceMapUrl = getSourceMapUrl( - generated.code, - JSON.stringify(generated.map) - ); - const codegenOutput = prettier.format(generated.code, { - semi: true, - parser: "babel", - plugins: [prettierParserBabel], + const tabs = new Map(); + const generator = HIR.run(func); + let ast; + while (true) { + const next = generator.next(); + if (next.done) { + ast = next.value; + break; + } + const result = next.value; + switch (result.kind) { + case "ast": { + const { code } = codegen(result.value, source); + tabs.set( + result.name, + + ); + break; + } + case "hir": { + const text = printHIR(result.value.body); + tabs.set( + result.name, + + ); + break; + } + case "reactive": { + const text = printReactiveFunction(result.value); + tabs.set( + result.name, + + ); + break; + } + default: { + throw new Error("Unexpected result kind"); + } + } + } + // Ensure that JS and the JS source map come first + const reorderedTabs = new Map(); + const { code, sourceMapUrl } = codegen(ast, source); + reorderedTabs.set("JS", ); + if (sourceMapUrl) { + reorderedTabs.set( + "SourceMap", + <> +