Top Related Projects
:snowman: Possibly the smallest compiler ever
A small, fast, JavaScript-based JavaScript parser
🐠 Babel is a compiler for writing next generation JavaScript.
An extremely fast bundler for the web
Rust-based platform for the Web
🗜 JavaScript parser, mangler and compressor toolkit for ES6+
Quick Overview
The Super Tiny Compiler is an ultra-simplified example of a compiler written in JavaScript. It's designed to be an educational tool, demonstrating the basic concepts of how a compiler works by transforming a simple custom language into JavaScript. The project aims to demystify the compilation process for beginners and intermediate developers.
Pros
- Highly educational and easy to understand for beginners
- Well-commented code that explains each step of the compilation process
- Compact codebase (around 1000 lines) that covers the essential compiler concepts
- Serves as a great starting point for learning about compilers and language design
Cons
- Extremely simplified, not representative of real-world compilers
- Limited functionality compared to production-ready compilers
- Only compiles a very basic custom language to JavaScript
- May oversimplify some complex concepts in compiler design
Code Examples
- Tokenization:
function tokenizer(input) {
let current = 0;
let tokens = [];
while (current < input.length) {
let char = input[current];
if (char === '(') {
tokens.push({
type: 'paren',
value: '('
});
current++;
continue;
}
// ... more token types
throw new TypeError('I dont know what this character is: ' + char);
}
return tokens;
}
This code snippet demonstrates the tokenization process, breaking down the input string into individual tokens.
- Parsing:
function parser(tokens) {
let current = 0;
function walk() {
let token = tokens[current];
if (token.type === 'number') {
current++;
return {
type: 'NumberLiteral',
value: token.value
};
}
// ... more node types
throw new TypeError(token.type);
}
let ast = {
type: 'Program',
body: []
};
while (current < tokens.length) {
ast.body.push(walk());
}
return ast;
}
This example shows how the parser constructs an Abstract Syntax Tree (AST) from the tokens.
- Code Generation:
function codeGenerator(node) {
switch (node.type) {
case 'Program':
return node.body.map(codeGenerator)
.join('\n');
case 'ExpressionStatement':
return (
codeGenerator(node.expression) +
';'
);
// ... more node types
default:
throw new TypeError(node.type);
}
}
This code snippet illustrates how the code generator transforms the AST into JavaScript code.
Getting Started
To use the Super Tiny Compiler:
-
Clone the repository:
git clone https://github.com/jamiebuilds/the-super-tiny-compiler.git
-
Navigate to the project directory:
cd the-super-tiny-compiler
-
Run the compiler:
const { tokenizer, parser, transformer, codeGenerator } = require('./the-super-tiny-compiler'); const input = '(add 2 (subtract 4 2))'; const output = codeGenerator(transformer(parser(tokenizer(input)))); console.log(output);
This will compile the input expression and output the resulting JavaScript code.
Competitor Comparisons
:snowman: Possibly the smallest compiler ever
Pros of the-super-tiny-compiler
- Extremely lightweight and easy to understand
- Well-documented with inline comments explaining each step
- Serves as an excellent educational resource for compiler basics
Cons of the-super-tiny-compiler
- Limited functionality compared to full-fledged compilers
- Not suitable for production use or complex language compilation
Code Comparison
Both repositories contain the same code, as they are identical. Here's a sample from the tokenizer function:
function tokenizer(input) {
let current = 0;
let tokens = [];
while (current < input.length) {
let char = input[current];
// ... (rest of the tokenizer logic)
}
return tokens;
}
The code in both repositories is identical, focusing on creating a simple compiler that transforms lisp-like function calls into C-like function calls. The project is designed to be educational and easy to understand, rather than for practical use in real-world scenarios.
Both repositories serve the same purpose: to provide a minimalistic example of how compilers work, breaking down the process into tokenization, parsing, traversing, and code generation. The code is well-commented and structured to help readers understand each step of the compilation process.
A small, fast, JavaScript-based JavaScript parser
Pros of Acorn
- More feature-rich and production-ready JavaScript parser
- Supports ECMAScript 2020 and JSX
- Highly performant and widely used in popular tools like Webpack and Rollup
Cons of Acorn
- Larger codebase, more complex to understand and modify
- Less suitable for educational purposes or learning compiler basics
- Requires more setup and configuration for basic usage
Code Comparison
The-Super-Tiny-Compiler:
function tokenizer(input) {
let current = 0;
let tokens = [];
// ... (simplified tokenization logic)
return tokens;
}
Acorn:
import * as acorn from "acorn";
const ast = acorn.parse("const answer = 42;", {
ecmaVersion: 2020
});
Summary
The-Super-Tiny-Compiler is designed for educational purposes, offering a simple and easy-to-understand implementation of a basic compiler. It's excellent for learning compiler concepts but lacks advanced features.
Acorn, on the other hand, is a full-featured JavaScript parser used in production environments. It offers support for modern ECMAScript features and high performance but comes with increased complexity and a steeper learning curve.
Choose The-Super-Tiny-Compiler for learning compiler basics or Acorn for robust JavaScript parsing in real-world applications.
🐠 Babel is a compiler for writing next generation JavaScript.
Pros of Babel
- Comprehensive and production-ready JavaScript compiler with extensive plugin ecosystem
- Supports a wide range of ECMAScript versions and proposals
- Actively maintained with regular updates and a large community
Cons of Babel
- Complex codebase with a steep learning curve for contributors
- Larger bundle size and potentially slower compilation times
- Requires configuration and setup for optimal use
Code Comparison
The-Super-Tiny-Compiler:
function tokenizer(input) {
let current = 0;
let tokens = [];
while (current < input.length) {
// Tokenization logic
}
return tokens;
}
Babel:
export default function(babel) {
return {
visitor: {
Identifier(path) {
// Transformation logic
}
}
};
}
Summary
The-Super-Tiny-Compiler is a simplified educational project designed to teach compiler basics, while Babel is a full-featured JavaScript compiler used in production environments. The-Super-Tiny-Compiler offers a more accessible codebase for learning, but lacks the extensive features and real-world applicability of Babel. Babel's complexity and robust feature set make it suitable for large-scale projects, but it may be overkill for simple transformations or educational purposes.
An extremely fast bundler for the web
Pros of esbuild
- Significantly faster build times due to its Go-based implementation
- Supports modern JavaScript features and TypeScript out of the box
- Offers a more comprehensive set of features for production-ready bundling
Cons of esbuild
- More complex codebase, making it harder to understand for educational purposes
- Larger project scope, which may be overkill for simple bundling tasks
- Requires Go knowledge for core development contributions
Code Comparison
the-super-tiny-compiler (JavaScript):
function tokenizer(input) {
let current = 0;
let tokens = [];
// ... (tokenization logic)
return tokens;
}
esbuild (Go):
func (p *parser) parseExpr() ast.Expr {
// ... (expression parsing logic)
return expr
}
The-super-tiny-compiler focuses on simplicity and educational value, implementing a basic compiler in JavaScript. esbuild, on the other hand, is a full-featured bundler written in Go, prioritizing performance and production readiness. While the-super-tiny-compiler is excellent for learning compiler basics, esbuild is better suited for real-world project bundling and optimization.
Rust-based platform for the Web
Pros of swc
- High-performance Rust-based compiler, significantly faster than traditional JavaScript-based tools
- Supports modern JavaScript and TypeScript features, including JSX and decorators
- Extensible plugin system for custom transformations
Cons of swc
- More complex codebase, harder to understand for beginners
- Requires Rust knowledge for core development and contributions
- Less educational value for learning compiler basics
Code Comparison
the-super-tiny-compiler (JavaScript):
function tokenizer(input) {
let current = 0;
let tokens = [];
// ... (tokenization logic)
return tokens;
}
swc (Rust):
pub fn tokenize(input: &str) -> Vec<Token> {
let mut lexer = Lexer::new(input);
let mut tokens = Vec::new();
// ... (tokenization logic)
tokens
}
The super-tiny-compiler is designed as a simple, educational tool to understand compiler basics, while swc is a production-ready, high-performance compiler. the-super-tiny-compiler uses JavaScript and focuses on clarity, making it easier for beginners to grasp compiler concepts. swc, written in Rust, prioritizes speed and features, making it suitable for large-scale projects but more challenging to comprehend for those new to compiler development.
🗜 JavaScript parser, mangler and compressor toolkit for ES6+
Pros of Terser
- More comprehensive JavaScript minification and optimization
- Actively maintained with regular updates and improvements
- Supports modern JavaScript features and syntax
Cons of Terser
- Larger codebase, more complex to understand and contribute to
- Focused on production use rather than educational purposes
- Requires more setup and configuration for optimal use
Code Comparison
The-Super-Tiny-Compiler:
function tokenizer(input) {
let current = 0;
let tokens = [];
while (current < input.length) {
// Tokenization logic
}
return tokens;
}
Terser:
function minify(files, options) {
options = defaults(options, {
compress: {},
mangle: true,
output: {}
});
// Minification logic
}
The-Super-Tiny-Compiler is designed as a simple, educational tool to demonstrate compiler concepts. It's easy to read and understand, making it ideal for learning purposes. However, it lacks the advanced features and optimizations found in Terser.
Terser, on the other hand, is a production-ready JavaScript minifier and optimizer. It offers more comprehensive minification techniques and supports a wider range of JavaScript features. While more complex, Terser is better suited for real-world applications and performance optimization.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Welcome to The Super Tiny Compiler!
This is an ultra-simplified example of all the major pieces of a modern compiler written in easy to read JavaScript.
Reading through the guided code will help you learn about how most compilers work from end to end.
Want to jump into the code? Click here
You can also check it out on Glitch
Why should I care?
That's fair, most people don't really have to think about compilers in their day jobs. However, compilers are all around you, tons of the tools you use are based on concepts borrowed from compilers.
But compilers are scary!
Yes, they are. But that's our fault (the people who write compilers), we've taken something that is reasonably straightforward and made it so scary that most think of it as this totally unapproachable thing that only the nerdiest of the nerds are able to understand.
Okay so where do I begin?
Awesome! Head on over to the the-super-tiny-compiler.js file.
I'm back, that didn't make sense
Ouch, I'm really sorry. Let me know how it can be improved.
Tests
Run with node test.js
Top Related Projects
:snowman: Possibly the smallest compiler ever
A small, fast, JavaScript-based JavaScript parser
🐠 Babel is a compiler for writing next generation JavaScript.
An extremely fast bundler for the web
Rust-based platform for the Web
🗜 JavaScript parser, mangler and compressor toolkit for ES6+
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot