Skip to content

Commit 87aa6d1

Browse files
Clean up
1 parent af12b74 commit 87aa6d1

11 files changed

Lines changed: 26 additions & 119 deletions

File tree

.github/workflows/mdbook.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Deploy Docs
22

33
on:
44
push:
5-
branches: [master] # build on every push to master
5+
branches: [master]
66
jobs:
77
build:
88
runs-on: ubuntu-latest
@@ -15,15 +15,14 @@ jobs:
1515
- name: Build book
1616
run: mdbook build docs
1717

18-
# Upload the generated site as an artifact that Pages can deploy
1918
- uses: actions/upload-pages-artifact@v3
2019
with:
2120
path: docs/book
2221

2322
deploy:
2423
needs: build
2524
permissions:
26-
pages: write # to push to gh-pages
25+
pages: write
2726
id-token: write
2827
runs-on: ubuntu-latest
2928
environment:

playground/README.md

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1 @@
1-
# React + TypeScript + Vite
2-
3-
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4-
5-
Currently, two official plugins are available:
6-
7-
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8-
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9-
10-
## Expanding the ESLint configuration
11-
12-
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
13-
14-
```js
15-
export default tseslint.config([
16-
globalIgnores(['dist']),
17-
{
18-
files: ['**/*.{ts,tsx}'],
19-
extends: [
20-
// Other configs...
21-
22-
// Remove tseslint.configs.recommended and replace with this
23-
...tseslint.configs.recommendedTypeChecked,
24-
// Alternatively, use this for stricter rules
25-
...tseslint.configs.strictTypeChecked,
26-
// Optionally, add this for stylistic rules
27-
...tseslint.configs.stylisticTypeChecked,
28-
29-
// Other configs...
30-
],
31-
languageOptions: {
32-
parserOptions: {
33-
project: ['./tsconfig.node.json', './tsconfig.app.json'],
34-
tsconfigRootDir: import.meta.dirname,
35-
},
36-
// other options...
37-
},
38-
},
39-
])
40-
```
41-
42-
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
43-
44-
```js
45-
// eslint.config.js
46-
import reactX from 'eslint-plugin-react-x'
47-
import reactDom from 'eslint-plugin-react-dom'
48-
49-
export default tseslint.config([
50-
globalIgnores(['dist']),
51-
{
52-
files: ['**/*.{ts,tsx}'],
53-
extends: [
54-
// Other configs...
55-
// Enable lint rules for React
56-
reactX.configs['recommended-typescript'],
57-
// Enable lint rules for React DOM
58-
reactDom.configs.recommended,
59-
],
60-
languageOptions: {
61-
parserOptions: {
62-
project: ['./tsconfig.node.json', './tsconfig.app.json'],
63-
tsconfigRootDir: import.meta.dirname,
64-
},
65-
// other options...
66-
},
67-
},
68-
])
69-
```
1+
# An Interactive REPL for tundra

playground/src/Editor.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ import { useCallback } from "react";
33
import MonacoEditor, { Monaco } from "@monaco-editor/react";
44

55
const registerTundra = (monaco: Monaco) => {
6-
/*──────────────── 1. Register the language ────────────────*/
76
monaco.languages.register({ id: "tundra" });
8-
9-
/*──────────────── 2. Tokenizer (Monarch) ───────────────────*/
107
monaco.languages.setMonarchTokensProvider("tundra", {
118
tokenizer: {
129
root: [
@@ -15,31 +12,26 @@ monaco.languages.setMonarchTokensProvider("tundra", {
1512
[/'[^']*'/, "string"], // single-quoted strings
1613
[/\b(var|fun|class|for|while|if|else|return|print)\b/, "keyword"],
1714
[/[\+\-\*\/%]|\*\*|==|!=|<=|>=|<|>/, "operator"],
18-
[/[{}\(\)\[\]:]/, "@brackets"], // include colon as bracket
15+
[/[{}\(\)\[\]:]/, "@brackets"],
1916
[/[a-zA-Z_]\w*/, "identifier"],
2017
[/#.*$/, "comment"],
2118
],
2219
},
2320
});
2421

25-
/*──────────────── 3. Language configuration for indentation ────────────*/
2622
monaco.languages.setLanguageConfiguration("tundra", {
2723
indentationRules: {
28-
// Increase indent after lines ending with ':'
2924
increaseIndentPattern: /^\s*(if|while|for|fun|class|else)\b.*:\s*$/,
30-
// Decrease indent for lines starting with 'else'
3125
decreaseIndentPattern: /^\s*(else)\b.*$/,
3226
},
3327
onEnterRules: [
3428
{
35-
// After a line ending with ':', increase indent
3629
beforeText: /^\s*(if|while|for|fun|class|else)\b.*:\s*$/,
3730
action: {
3831
indentAction: monaco.languages.IndentAction.Indent,
3932
},
4033
},
4134
{
42-
// For 'else' statements, align with the corresponding 'if'
4335
beforeText: /^\s*else\s*:\s*$/,
4436
action: {
4537
indentAction: monaco.languages.IndentAction.Outdent,
@@ -52,7 +44,7 @@ monaco.languages.setLanguageConfiguration("tundra", {
5244
],
5345
});
5446

55-
/*──────────────── 4. Snippet-style completions ─────────────*/
47+
5648
monaco.languages.registerCompletionItemProvider("tundra", {
5749
provideCompletionItems: (model, position) => {
5850
const word = model.getWordUntilPosition(position);
@@ -144,7 +136,6 @@ monaco.languages.registerCompletionItemProvider("tundra", {
144136
},
145137
});
146138

147-
/*──────────────── 5. (Optional) turn off the default JS/TS diagnostics ──*/
148139
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
149140
noSemanticValidation: true,
150141
noSyntaxValidation: true,
@@ -157,7 +148,7 @@ interface Props {
157148
}
158149

159150
export const Editor = ({ code, setCode }: Props) => {
160-
// run once, before the editor mounts
151+
161152
const handleBeforeMount = useCallback((monaco: Monaco) => {
162153
registerTundra(monaco);
163154
}, []);

playground/src/monaco-tundra.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import * as monaco from "monaco-editor";
22

3-
/*──────────────── 1. Register the language ────────────────*/
43
monaco.languages.register({ id: "tundra" });
54

6-
/*──────────────── 2. Tokenizer (Monarch) ───────────────────*/
75
monaco.languages.setMonarchTokensProvider("tundra", {
86
tokenizer: {
97
root: [
@@ -12,31 +10,30 @@ monaco.languages.setMonarchTokensProvider("tundra", {
1210
[/'[^']*'/, "string"], // single-quoted strings
1311
[/\b(var|fun|class|for|while|if|else|return|print)\b/, "keyword"],
1412
[/[\+\-\*\/%]|\*\*|==|!=|<=|>=|<|>/, "operator"],
15-
[/[{}\(\)\[\]:]/, "@brackets"], // include colon as bracket
13+
[/[{}\(\)\[\]:]/, "@brackets"],
1614
[/[a-zA-Z_]\w*/, "identifier"],
1715
[/#.*$/, "comment"],
1816
],
1917
},
2018
});
2119

22-
/*──────────────── 3. Language configuration for indentation ────────────*/
2320
monaco.languages.setLanguageConfiguration("tundra", {
2421
indentationRules: {
25-
// Increase indent after lines ending with ':'
22+
2623
increaseIndentPattern: /^\s*(if|while|for|fun|class|else)\b.*:\s*$/,
27-
// Decrease indent for lines starting with 'else'
24+
2825
decreaseIndentPattern: /^\s*(else)\b.*$/,
2926
},
3027
onEnterRules: [
3128
{
32-
// After a line ending with ':', increase indent
29+
3330
beforeText: /^\s*(if|while|for|fun|class|else)\b.*:\s*$/,
3431
action: {
3532
indentAction: monaco.languages.IndentAction.Indent,
3633
},
3734
},
3835
{
39-
// For 'else' statements, align with the corresponding 'if'
36+
4037
beforeText: /^\s*else\s*:\s*$/,
4138
action: {
4239
indentAction: monaco.languages.IndentAction.Outdent,
@@ -49,7 +46,7 @@ monaco.languages.setLanguageConfiguration("tundra", {
4946
],
5047
});
5148

52-
/*──────────────── 4. Snippet-style completions ─────────────*/
49+
5350
monaco.languages.registerCompletionItemProvider("tundra", {
5451
provideCompletionItems: (model, position) => {
5552
const word = model.getWordUntilPosition(position);
@@ -141,7 +138,7 @@ monaco.languages.registerCompletionItemProvider("tundra", {
141138
},
142139
});
143140

144-
/*──────────────── 5. (Optional) turn off the default JS/TS diagnostics ──*/
141+
145142
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
146143
noSemanticValidation: true,
147144
noSyntaxValidation: true,

tundra-cli/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,21 @@ fn main() {
3535
}
3636
};
3737

38-
// 1) Compile
38+
// Compile
3939
let chunk = Rc::new(RefCell::new(Chunk::new()));
4040
let mut compiler = Compiler::new(chunk.clone());
4141
if !compiler.compile(&source) {
4242
eprintln!("Compile error");
4343
process::exit(1);
4444
}
4545

46-
// Optional bytecode dump
46+
// bytecode dump
4747
let debug = args.any(|a| a == "--debug");
4848
if debug {
4949
disassemble_chunk(&chunk.borrow(), &format!("== {} ==", script));
5050
}
5151

52-
// 2) Run with **interpreter only** (no JIT)
52+
// interpreter only run
5353
let mut vm = VM::new_interpreter_only(chunk, Box::leak(Box::new(std::io::stdout())));
5454
match vm.run() {
5555
InterpretResult::Ok => {}

tundra/src/bytecode/chunk.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::opcode::OpCode;
44
use crate::bytecode::value::Value;
55

66
/// A compiled “chunk” of code:
7-
/// - `code` holds your high-level `OpCode` instructions
7+
/// - `code` holds high-level `OpCode` instructions
88
/// - `constants` is the literal pool
99
/// - `lines[i]` is the source‐line for `code[i]`
1010
/// - `max_register` to allocate CraneLift Variables

tundra/src/bytecode/debug.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use crate::bytecode::chunk::Chunk;
44

5-
/// A one‐pass disassembler: we print each instruction via its Debug impl.
5+
/// A one‐pass disassembler
66
pub fn disassemble_chunk(chunk: &Chunk, name: &str) {
77
println!("== {} ==", name);
88
for (offset, instr) in chunk.code.iter().enumerate() {

tundra/src/bytecode/opcode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub enum OpCode {
4747
}
4848

4949
impl OpCode {
50-
/// A compact numeric tag for each variant (useful for a real byte-buffer backend)
50+
/// A compact numeric tag for each variant
5151
pub fn tag(&self) -> u8 {
5252
match self {
5353
OpCode::LoadConstant(_, _) => 0x01,
@@ -91,7 +91,7 @@ impl OpCode {
9191
OpCode::IncLoopIfLess(_, _, _) => 0x27,
9292
}
9393
}
94-
///Convert to bytes (For Debugging)
94+
///Convert to bytes
9595
pub fn to_bytes(&self) -> Vec<u8> {
9696
let mut buf = vec![self.tag()];
9797
match self {

tundra/src/bytecode/value.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,14 @@ pub enum ValueType {
1111
Float(f64),
1212
Char(char),
1313
Array(Rc<RefCell<Vec<Value>>>),
14-
// A Rust‐side builtin function:
1514
NativeFunction(fn(&[Value]) -> Value, usize /*arity*/),
16-
// A user‐defined function
1715
Function(Rc<RefCell<FunctionObject>>),
1816
}
1917
#[derive(Debug, Clone, PartialEq)]
2018
pub struct Value {
2119
pub value: ValueType,
2220
}
23-
/* ───────── Encoding helpers ───────── */
21+
2422

2523
pub const TAG_BITS: u64 = 0b111;
2624
pub const TAG_PTR: u64 = 0b000;
@@ -144,15 +142,14 @@ impl Value {
144142
/// loss-less, type-preserving packing into a single register
145143
pub fn as_i64(&self) -> i64 {
146144
match &self.value {
147-
/* POD scalar slots */
145+
148146
ValueType::Int(i) => ((*i as u64) << 3 | TAG_INT) as i64,
149147
ValueType::Bool(false) => TAG_BOOL as i64,
150148
ValueType::Bool(true) => (1u64 << 3 | TAG_BOOL) as i64,
151149
ValueType::None => TAG_NONE as i64,
152150
ValueType::Char(c) => ((*c as u64) << 3 | TAG_CHAR) as i64,
153151
ValueType::Float(f) => f.to_bits() as i64,
154152

155-
/* everything heap-allocated – we just use the raw pointer */
156153
ValueType::String(s) => {
157154
let p = s.as_ptr() as u64;
158155
(p | TAG_PTR) as i64
@@ -212,7 +209,7 @@ impl Value {
212209
}
213210
ValueType::Char(c) => {
214211
let mut b = vec![0x05]; // Char tag
215-
b.extend(&(*c as u32).to_le_bytes()); // char → 4-byte Unicode scalar
212+
b.extend(&(*c as u32).to_le_bytes());
216213
b
217214
}
218215
ValueType::String(s) => {

tundra/src/lib.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,9 @@ impl std::io::Write for OutputCapture {
3939
}
4040

4141
pub fn run(src: &str) -> Result<String> {
42-
// Create a shared buffer for capturing output
42+
// a shared buffer for capturing output
4343
let output_buffer = Rc::new(RefCell::new(Vec::<u8>::new()));
4444

45-
// Create the output capture and leak it to get a 'static reference
4645
let output_capture = Box::new(OutputCapture::new(output_buffer.clone()));
4746
let output_ref: &'static mut dyn std::io::Write = Box::leak(output_capture);
4847

@@ -63,15 +62,10 @@ pub fn run(src: &str) -> Result<String> {
6362
InterpretResult::CompileError => unreachable!(),
6463
}
6564
};
66-
67-
// Extract the output from the shared buffer
6865
let output_bytes = {
6966
let buffer = output_buffer.borrow();
7067
buffer.clone()
7168
};
72-
7369
let output_string = String::from_utf8(output_bytes).unwrap_or_default();
74-
75-
// Return the result with the captured output
7670
result.map(|_| output_string)
7771
}

0 commit comments

Comments
 (0)