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", + <> +