summaryrefslogtreecommitdiff
path: root/static/js/main.js
blob: 3815538fb9050881b2c429e6851fa5c9b865560b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
const PROG_DEFAULT = `DISCOVER HOW TO factorial WITH n
WE SAID
    WHAT IF n IS ACTUALLY 0
    WE SAID
        SHOCKING DEVELOPMENT 1
    END OF STORY
    LIES! WE SAID
        SHOCKING DEVELOPMENT n MULTIPLY factorial OF n SUBTRACT 1
    END OF STORY
END OF STORY

EXPERTS CLAIM result TO BE factorial OF 10
YOU WON'T WANT TO MISS 'RESULT IS'
YOU WON'T WANT TO MISS result

PLEASE LIKE AND SUBSCRIBE`;

const HEADLINES = [
    `You Won't Believe What This Programming Language Can Do!`,
    `The Best Programming Language You Haven't Heard Of (It Will Surprise You!)`,
    `Shocking New Programming Language Bewilders Programmers at Google and Facebook!`,
    `Programmer Who Made Everything Now Predicts the Next Big Language!`,
    `The Secret Programming Language Every 10x Programmer Recommends!`,
];

function randomHeadline() {
    return HEADLINES[~~(Math.random() * HEADLINES.length)];
}

const {
    Component,
} = window.Torus;

class Editor extends Component {
    init() {
        this.prog = PROG_DEFAULT;
        // script appends to it
        this.output = '';
        this.errors = '';

        this.handleRun = () => this.eval();
        this.handleReset = () => {
            this.prog = PROG_DEFAULT;
            this.render();
        }
        this.handleInput = evt => {
            this.prog = evt.target.value;
            this.render();
        }
    }
    eval() {
        this.output = '';
        this.errors = '';
        try {
            const tokens = tokenize(this.prog);
            const nodes = new Parser(tokens).parse();
            const env = new Environment({
                print: s => {
                    this.output += s.toString() + '\n';
                    this.render();
                },
            });
            env.run(nodes);
        } catch (e) {
            this.errors = e.toString();
        }
        this.render();
    }
    compose() {
        return jdom`<div class="editor fixed block">
            <div class="controls">
                ${this.prog === PROG_DEFAULT ? null : 
                    jdom`<button class="block"
                        onclick=${this.handleReset}>Reset</button>`}
                <button class="accent block"
                    onclick=${this.handleRun}>Run!</button>
            </div>
            <div class="code">
                <div class="filler">
                    ${this.prog.split('\n')
                        .map(line => jdom`<p>${line.trim() ? line : '-'}</p>`)}
                </div>
                <textarea class="editor-input" cols="30" rows="10"
                    value=${this.prog}
                    oninput=${this.handleInput}>
                </textarea>
            </div>
            <div class="output">
                ${this.output ? this.output
                    .split('\n')
                    .map(line => jdom`<code class="output-line">${line}</code>`)
                    : jdom`<code class="no-output">No output.</code>`}
            </div>
            ${this.errors ? jdom`<div class="errors">
                ${this.errors.split('\n').map(line => jdom`<code>${line}</code>`)}
            </div>` : null}
        </div>`;
    }
}

class App extends Component {
    init() {
        this.editor = new Editor();
    }
    compose() {
        return jdom`<main>
            <header>
                <h1>${randomHeadline()}</h1>
                <nav>
                    <a href="https://github.com/thesephist/tabloid"
                        target="_blank" noopener noreferer>GitHub</a>
                    <a href="https://dotink.co/posts/tabloid/"
                        target="_blank" noopener noreferer>Blog post</a>
                </nav>
                <p class="subtitle">
                    <strong class="lang fixed inline block">Tabloid:</strong> The Clickbait Headline Programming Language
                </p>
            </header>
            ${this.editor.node}
            <h2>What?</h2>
            <h2>But why?</h2>
            <h2>Does it actually work?</h2>
            <footer>
                <p>
                    Tabloid is a project by
                    <a href="https://thesephist.com/">@thesephist</a>,
                    website built with
                    <a href="https://github.com/thesephist/torus">Torus</a>
                    and
                    <a href="https://thesephist.github.io/blocks.css/">blocks.css</a>.
                </p>
            </footer>
        </main>`;
    }
}

const app = new App();
document.body.appendChild(app.node);