Skip to content

Commit

Permalink
Refactor pprinter page into components and page
Browse files Browse the repository at this point in the history
  • Loading branch information
davazp committed Apr 3, 2020
1 parent a3c658e commit c9f20a1
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 170 deletions.
177 changes: 177 additions & 0 deletions packages/liphe/components/PPrinter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/* eslint-disable react/jsx-key */

import {
Encoder,
isExpression,
Expression,
Module,
pprintAs,
printTypeWithNormalizer,
Syntax,
SDefinition,
Type,
Typed,
TypeVariableNormalizer,
createVariableNormalizer,
} from "@delisp/core";
import React from "react";
import styled from "styled-components";

const LINE_WIDTH = 40;

export function ModuleExplorer({ module: m }: { module: Module<Typed | {}> }) {
return (
<div>
{m.body.map((s, i) => (
<SyntaxExplorer key={i} syntax={s} />
))}
</div>
);
}

function SyntaxExplorer({ syntax }: { syntax: Syntax<Typed | {}> }) {
switch (syntax.node.tag) {
case "definition":
return (
<DefinitionExplorer definition={{ ...syntax, node: syntax.node }} />
);
default:
return (
<GenericSyntaxExplorer
syntax={syntax}
normalizer={createVariableNormalizer()}
/>
);
}
}

const Definition = styled.div`
border: 1px solid lightGray;
margin: 20px;
padding: 2px;
`;

function DefinitionExplorer({
definition,
}: {
definition: SDefinition<Typed | {}>;
}) {
const normalizer = createVariableNormalizer();
const type = (definition.node.value.info as any).resultingType;

return (
<Definition>
<pre>Definition</pre> <pre>{definition.node.variable.name}</pre>
{type && (
<div>
Type <TypeExplorer type={type} normalizer={normalizer} />
</div>
)}
<GenericSyntaxExplorer
syntax={definition.node.value}
normalizer={normalizer}
/>
</Definition>
);
}

const Code = styled.pre`
background-color: white;
padding: 5px;
font-family: courier;
.delimiter {
color: #bbb;
}
.variable-definition {
color: #c42;
}
.keyword {
color: blue;
}
.boolean {
color: red;
}
.number {
color: orange;
}
.string {
color: red;
}
`;

const Token = styled.span`
&:hover {
background-color: #88f;
}
`;

function getDisplayExpressionType(
expr: Expression<Typed>,
normalizer: TypeVariableNormalizer
) {
if (!expr.info.selfType) return undefined;
return `${printTypeWithNormalizer(expr.info.selfType, normalizer)}`;
}

function TypeExplorer({
type,
normalizer,
}: {
type: Type;
normalizer: TypeVariableNormalizer;
}) {
return <span>`{printTypeWithNormalizer(type, normalizer)}`</span>;
}

function createPrettierEncoder(
normalizer: TypeVariableNormalizer
): Encoder<React.ReactElement[]> {
return {
fromString: function PrettierEncoder(
x: string,
kind: string[],
source?: Syntax<Typed>
) {
return [
<Token
data-source={source}
className={kind.join(" ")}
onClick={() => {
console.log({ source });
}}
title={
source && isExpression(source)
? getDisplayExpressionType(source, normalizer)
: undefined
}
>
{x}
</Token>,
];
},
concat: (...args: React.ReactElement[][]): React.ReactElement[] =>
args.flat(1),
};
}

export function GenericSyntaxExplorer({
syntax,
normalizer,
}: {
syntax: Syntax;
normalizer: TypeVariableNormalizer;
}) {
return (
<Code>
{pprintAs(syntax, LINE_WIDTH, createPrettierEncoder(normalizer))}
</Code>
);
}

/* eslint-enable react/jsx-key */
2 changes: 1 addition & 1 deletion packages/liphe/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as Delisp from "@delisp/core";
import { Typed } from "@delisp/core";
import { PageLayout } from "../components/PageLayout";

import { GenericSyntaxExplorer } from "./pprinter";
import { GenericSyntaxExplorer } from "../components/PPrinter";

import styles from "./index.module.css";

Expand Down
171 changes: 2 additions & 169 deletions packages/liphe/pages/pprinter.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
/* eslint-disable react/jsx-key */

import {
compileModuleToString,
Encoder,
inferModule,
isExpression,
Expression,
compileModuleToString,
macroexpandModule,
Module,
pprintAs,
printTypeWithNormalizer,
readModule,
Syntax,
SDefinition,
Type,
Typed,
TypeVariableNormalizer,
createVariableNormalizer,
} from "@delisp/core";
import React, { useState } from "react";
import styled, { css } from "styled-components";
import { PageLayout } from "../components/PageLayout";

const LINE_WIDTH = 40;
import { ModuleExplorer } from "../components/PPrinter";

interface ViewProps {
code: string;
Expand Down Expand Up @@ -100,62 +88,6 @@ function AST({ code }: { code: string }) {
);
}

function ModuleExplorer({ module: m }: { module: Module<Typed | {}> }) {
return (
<div>
{m.body.map((s, i) => (
<SyntaxExplorer key={i} syntax={s} />
))}
</div>
);
}

function SyntaxExplorer({ syntax }: { syntax: Syntax<Typed | {}> }) {
switch (syntax.node.tag) {
case "definition":
return (
<DefinitionExplorer definition={{ ...syntax, node: syntax.node }} />
);
default:
return (
<GenericSyntaxExplorer
syntax={syntax}
normalizer={createVariableNormalizer()}
/>
);
}
}

const Definition = styled.div`
border: 1px solid lightGray;
margin: 20px;
padding: 2px;
`;

function DefinitionExplorer({
definition,
}: {
definition: SDefinition<Typed | {}>;
}) {
const normalizer = createVariableNormalizer();
const type = (definition.node.value.info as any).resultingType;

return (
<Definition>
<pre>Definition</pre> <pre>{definition.node.variable.name}</pre>
{type && (
<div>
Type <TypeExplorer type={type} normalizer={normalizer} />
</div>
)}
<GenericSyntaxExplorer
syntax={definition.node.value}
normalizer={normalizer}
/>
</Definition>
);
}

const ViewButton = styled.button`
${(props: { selected?: boolean }) =>
props.selected &&
Expand All @@ -171,105 +103,6 @@ const Editor = styled.textarea`
font-size: 1.5em;
`;

const Code = styled.pre`
background-color: white;
padding: 5px;
font-family: courier;
.delimiter {
color: #bbb;
}
.variable-definition {
color: #c42;
}
.keyword {
color: blue;
}
.boolean {
color: red;
}
.number {
color: orange;
}
.string {
color: red;
}
`;

const Token = styled.span`
&:hover {
background-color: #88f;
}
`;

function getDisplayExpressionType(
expr: Expression<Typed>,
normalizer: TypeVariableNormalizer
) {
if (!expr.info.selfType) return undefined;
return `${printTypeWithNormalizer(expr.info.selfType, normalizer)}`;
}

function TypeExplorer({
type,
normalizer,
}: {
type: Type;
normalizer: TypeVariableNormalizer;
}) {
return <span>`{printTypeWithNormalizer(type, normalizer)}`</span>;
}

function createPrettierEncoder(
normalizer: TypeVariableNormalizer
): Encoder<React.ReactElement[]> {
return {
fromString: function PrettierEncoder(
x: string,
kind: string[],
source?: Syntax<Typed>
) {
return [
<Token
data-source={source}
className={kind.join(" ")}
onClick={() => {
console.log({ source });
}}
title={
source && isExpression(source)
? getDisplayExpressionType(source, normalizer)
: undefined
}
>
{x}
</Token>,
];
},
concat: (...args: React.ReactElement[][]): React.ReactElement[] =>
args.flat(1),
};
}

export function GenericSyntaxExplorer({
syntax,
normalizer,
}: {
syntax: Syntax;
normalizer: TypeVariableNormalizer;
}) {
return (
<Code>
{pprintAs(syntax, LINE_WIDTH, createPrettierEncoder(normalizer))}
</Code>
);
}

export default function App() {
const [code, setCode] = useState("");
return (
Expand Down

0 comments on commit c9f20a1

Please sign in to comment.