Skip to content

Commit 24e2c21

Browse files
committed
Merge remote-tracking branch 'origin/simon' into language-validation
2 parents 5dbbebe + ab69023 commit 24e2c21

10 files changed

Lines changed: 159 additions & 72 deletions

File tree

public/glorpcat.png

68.9 KB
Loading

public/glorpcat1.png

62.3 KB
Loading

public/glorpcat2.png

67.4 KB
Loading

src/components/InfoComponent.tsx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react'
2+
import Image from 'react'
3+
const InfoComponent = () => {
4+
return (
5+
<div className="flex-1 bg-[#2a2a2a] rounded-2xl p-3 flex flex-col gap-3">
6+
7+
{/* Title */}
8+
<h1 className="text-center text-5xl tracking-widest text-green-400">
9+
GLORPYTHON
10+
</h1>
11+
12+
{/* Code panels */}
13+
<div className="flex gap-3">
14+
{/* Python */}
15+
<div className="m-5 flex-1 bg-[#3a7bd5] rounded-2xl overflow-hidden">
16+
<div className="bg-[#2d5fa8] text-white text-s text-center py-2 tracking-widest font-bold">
17+
*** PYTHON CODE ***
18+
</div>
19+
<div className="bg-[#4a8be0] m-2 rounded-xl p-3">
20+
<pre className="text-white text-xs leading-relaxed m-0">{`nums = [1,2,3]
21+
sum = 0
22+
for i in nums:
23+
sum += i
24+
print(sum)`}</pre>
25+
</div>
26+
</div>
27+
28+
{/* Alien */}
29+
<div className="m-5 flex-1 bg-[#2d7a3a] rounded-2xl overflow-hidden">
30+
<div className="bg-[#1f5c29] text-white text-s text-center py-2 tracking-widest font-bold">
31+
*** ALIEN CODE ***
32+
</div>
33+
<div className="bg-[#3a9447] transition m-2 rounded-xl p-3">
34+
<pre className="text-white text-xs leading-relaxed m-0">{`nums eats [1,2,3]
35+
sum eats 0
36+
i eats nums slowly:
37+
sum eats more i
38+
print eats sum`}</pre>
39+
</div>
40+
</div>
41+
</div>
42+
43+
{/* Goal text */}
44+
<div className="text-gray-300 text-m leading-relaxed text-center" >
45+
<p className="mb-2">The code above are equivalent.</p>
46+
<p className="mb-2">YOUR GOAL: Write a program in ALIEN CODE that outputs the<br />
47+
SQUARE OF THE LENGTH OF nums.</p>
48+
<p className="mb-2">Assume nums is already defined.</p>
49+
<p>(Hint: you cannot use any +-*/ or **)</p>
50+
</div>
51+
52+
<div className="group mb-2 h-10 flex">
53+
<img className="h-40 ml-40" src="glorpcat1.png"/>
54+
</div>
55+
</div>
56+
)
57+
}
58+
59+
export default InfoComponent

src/components/LevelComponent.tsx

Lines changed: 9 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { renderAlien } from "../language/render/renderAlien";
66
import { parsePythonWithTreeSitter } from "../language/parse/parsePythonWithTreeSitter";
77
import type { ProgramNode } from "../language/types";
88
import { validateAlienSource } from "../language/validate/validateAlienSource";
9+
import OutputComponent from './OutputComponent'
10+
import InfoComponent from './InfoComponent'
911

1012
export default function LevelComponent() {
1113
const [code, setCode] = useState("")
@@ -120,6 +122,11 @@ sys.stdout = io.StringIO()
120122
}
121123

122124
return (
125+
<div className="w-screen h-screen flex gap-10 p-4 font-mono overflow-hidden">
126+
<div className="flex gap-4 p-4 w-6/7 mx-auto">
127+
128+
<div className="flex-1 bg-[#2a2a2a] rounded-2xl p-3 flex flex-col gap-3">
129+
<InfoComponent />
123130
<div className="w-screen h-screen flex gap-4 p-4 bg-[#0a0f2e] font-mono overflow-hidden">
124131

125132
{/* Left panel */}
@@ -153,47 +160,9 @@ sys.stdout = io.StringIO()
153160
</div>
154161
</div>
155162
</div>
156-
157-
{/* Goal text */}
158-
<div className="text-gray-300 text-xs leading-relaxed">
159-
<p className="mb-2">The code above are equivalent.</p>
160-
<p className="mb-2">YOUR GOAL: Write a program in<br />
161-
ALIEN CODE that outputs the<br />
162-
SQUARE OF THE LENGTH OF nums.</p>
163-
<p className="mb-2">Assume nums is already defined.</p>
164-
<p>(Hint: you cannot use any +-*/ or **)</p>
163+
<div className="flex-1 bg-[#2a2a2a] rounded-2xl p-3 flex flex-col gap-3">
164+
<OutputComponent />
165165
</div>
166-
167-
</div>
168-
169-
{/* Right panel */}
170-
<div className="flex-1 bg-[#2a2a2a] rounded-2xl p-5 flex flex-col gap-3">
171-
172-
{/* Editor */}
173-
<textarea
174-
value={code}
175-
onChange={(e) => setCode(e.target.value)}
176-
onKeyDown={handleKeyDown}
177-
spellCheck={false}
178-
placeholder="write code here!"
179-
className="flex-1 bg-[#3a3a3a] text-gray-300 text-sm font-mono p-4 rounded-xl resize-none outline-none placeholder-gray-500"
180-
/>
181-
182-
{/* Submit button */}
183-
<button
184-
onClick={runCode}
185-
disabled={!pyodideReady}
186-
className="bg-green-600 hover:bg-green-500 disabled:bg-gray-600 text-white font-bold py-2 px-6 rounded-lg text-sm w-fit"
187-
>
188-
{pyodideReady ? "submit" : "loading python..."}
189-
</button>
190-
191-
{/* Output */}
192-
<div className="text-gray-300 text-sm font-bold tracking-widest">OUTPUT:</div>
193-
<div className="bg-[#3a3a3a] rounded-xl p-4 text-gray-400 text-sm font-mono min-h-[60px]">
194-
{output || <span className="text-gray-600">output</span>}
195-
</div>
196-
197166
</div>
198167

199168
</div>

src/components/OutputComponent.tsx

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React, { useState, useEffect, useRef } from 'react'
2+
3+
const OutputComponent = () => {
4+
const [code, setCode] = useState("")
5+
const [output, setOutput] = useState("")
6+
const [pyodideReady, setPyodideReady] = useState(false)
7+
const pyodideRef = useRef<any>(null)
8+
const outputExpected = "5"
9+
useEffect(() => {
10+
const loadPyodide = async () => {
11+
// @ts-ignore
12+
pyodideRef.current = await window.loadPyodide()
13+
setPyodideReady(true)
14+
}
15+
loadPyodide()
16+
}, [])
17+
18+
const runCode = async () => {
19+
if (!pyodideRef.current) return
20+
await pyodideRef.current.runPythonAsync(`
21+
import sys, io
22+
sys.stdout = io.StringIO()
23+
`)
24+
try {
25+
await pyodideRef.current.runPythonAsync(code)
26+
const result = await pyodideRef.current.runPythonAsync(`sys.stdout.getvalue()`)
27+
setOutput(result)
28+
} catch (err: any) {
29+
setOutput(err.message)
30+
}
31+
}
32+
33+
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
34+
if (e.key === "Tab") {
35+
e.preventDefault()
36+
const el = e.target as HTMLTextAreaElement
37+
const { selectionStart, selectionEnd } = el
38+
const newValue = code.slice(0, selectionStart) + " " + code.slice(selectionEnd)
39+
setCode(newValue)
40+
requestAnimationFrame(() => {
41+
el.selectionStart = el.selectionEnd = selectionStart + 4
42+
})
43+
}
44+
}
45+
46+
return (
47+
<div className="flex-1 p-3 flex flex-col gap-3">
48+
{/* Editor */}
49+
<textarea
50+
value={code}
51+
onChange={(e) => setCode(e.target.value)}
52+
onKeyDown={handleKeyDown}
53+
spellCheck={false}
54+
placeholder="write code here!"
55+
className=" bg-[#3a3a3a] text-gray-300 text-sm font-mono p-4 rounded-xl resize-none outline-none placeholder-gray-500 flex-1"
56+
/>
57+
58+
{/* Submit button */}
59+
<button
60+
onClick={runCode}
61+
disabled={!pyodideReady}
62+
className="bg-green-600 hover:bg-green-500 hover:animate-pulse disabled:bg-gray-600 text-white font-bold py-2 px-6 rounded-lg text-sm w-fit transition duration:300"
63+
>
64+
{pyodideReady ? "submit" : "loading python..."}
65+
</button>
66+
67+
{/* Output */}
68+
<div className="text-gray-300 text-sm font-bold tracking-widest">OUTPUT:</div>
69+
<div className="bg-[#3a3a3a] rounded-xl p-4 text-gray-100 text-sm font-mono min-h-10">
70+
{output || <span className="text-gray-100">output appears here</span>}
71+
</div>
72+
73+
<div className="text-gray-300 text-sm font-bold tracking-widest">EXPECTED OUTPUT:</div>
74+
<div className="bg-[#3a3a3a] rounded-xl p-4 text-sm font-mono min-h-10">
75+
<span className="text-gray-100">{outputExpected}</span>
76+
</div>
77+
</div>
78+
)
79+
}
80+
81+
export default OutputComponent
82+

src/components/button/Button.module.css

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/components/button/Button.tsx

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/index.css

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1-
@import "tailwindcss";
1+
@import "tailwindcss";
2+
@theme {
3+
--animate-pulse: pulse 1.5s ease-in-out infinite;
4+
@keyframes pulse {
5+
50% {
6+
opacity: 0.7;
7+
}
8+
}
9+
}

src/pages/home/Home.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import Button from "../../components/button/Button";
21
import styles from "./Home.module.css";
32
import {useState} from "react";
43
import LevelComponent from "../../components/LevelComponent";

0 commit comments

Comments
 (0)