#intermediate-representation #typescript-compiler #expression #optimization #constant #flow-graph #elimination #control-flow-graph

typescript-ir

Intermediate representation for TypeScript compiler

5 releases

Uses new Rust 2024

0.0.4 Mar 30, 2026
0.0.3 Mar 28, 2026
0.0.2 Mar 27, 2026
0.0.1 Mar 25, 2026
0.0.0 Mar 24, 2026

#621 in Programming languages


Used in 3 crates

MIT license

165KB
3.5K SLoC

๐Ÿ”„ typescript-ir

Rusty TypeScript Intermediate Representation ๐Ÿฆ€โšก๏ธ

Crate Rust Edition


๐Ÿ“‹ Introduction

typescript-ir is the intermediate representation layer for the Rusty TypeScript compiler. It transforms AST into optimized IR and provides various optimization and analysis capabilities, serving as the bridge between parsing and code generation.

โœจ Core Features

Feature Description Status
๐Ÿ”„ AST โ†’ IR Transform Oak AST to internal IR โœ… Ready
โšก Constant Folding Compile-time constant expression evaluation โœ… Ready
๐Ÿ—‘๏ธ Dead Code Elimination Remove unreachable code โœ… Ready
๐ŸŒŠ Control Flow Graph CFG construction and analysis โœ… Ready
๐ŸŽฏ Type Information Type-aware IR representation โœ… Ready
๐Ÿ” Visitor Pattern Flexible IR traversal โœ… Ready

๐Ÿš€ Quick Start

Add Dependency

[dependencies]
typescript-ir = { path = "../compilers/typescript-ir" }

Basic Usage

use typescript_ir::{Program, Expression, Statement, BinaryOp};
use typescript_types::TsValue;

fn main() {
    // ๐Ÿ“ Create IR program
    let program = Program {
        statements: vec![
            Statement::VariableDeclaration {
                name: "x".to_string(),
                ty: None,
                initializer: Some(Box::new(Expression::Binary {
                    left: Box::new(Expression::Literal(TsValue::Number(10.0))),
                    op: BinaryOp::Add,
                    right: Box::new(Expression::Literal(TsValue::Number(20.0))),
                })),
            }
        ],
    };
    
    println!("๐ŸŽฏ IR program created successfully: {:?}", program);
}

AST to IR Conversion

use typescript_ir::ast_to_ir;
use oak_typescript::ast::TypeScriptRoot;

fn compile(ast: &TypeScriptRoot) -> Program {
    // ๐Ÿ”„ Convert Oak AST to IR
    let ir = ast_to_ir::program(ast);
    
    println!("โœ… AST to IR conversion completed");
    ir
}

Expression Optimization

use typescript_ir::{TypedExpression, Expression, TypeAnnotation};

fn optimize_expr(expr: Expression) -> TypedExpression {
    // ๐ŸŽฏ Create typed expression
    let typed = TypedExpression::new(expr, TypeAnnotation::Number);
    
    // โšก Perform optimization
    let optimized = typed.optimize();
    
    println!("๐Ÿš€ Optimization completed, is constant: {}", optimized.is_constant);
    optimized
}

โšก Optimization Features

Constant Folding

use typescript_ir::{TypedExpression, Expression, TypeAnnotation, BinaryOp};
use typescript_types::TsValue;

// Input: 10 + 20 * 2
let expr = Expression::Binary {
    left: Box::new(Expression::Literal(TsValue::Number(10.0))),
    op: BinaryOp::Add,
    right: Box::new(Expression::Binary {
        left: Box::new(Expression::Literal(TsValue::Number(20.0))),
        op: BinaryOp::Mul,
        right: Box::new(Expression::Literal(TsValue::Number(2.0))),
    }),
};

let typed = TypedExpression::new(expr, TypeAnnotation::Number);
let optimized = typed.optimize();

// Output: 50 (constant value)
assert!(optimized.is_constant);
assert_eq!(optimized.constant_value, Some(TsValue::Number(50.0)));

Control Flow Graph

use typescript_ir::ControlFlowGraph;

// Create CFG
let mut cfg = ControlFlowGraph::new();

// Add nodes
let node_a = cfg.add_node();
let node_b = cfg.add_node();
let node_c = cfg.add_node();

// Add edges
cfg.add_edge(node_a, node_b);
cfg.add_edge(node_b, node_c);

println!("๐ŸŒŠ CFG node count: {}", cfg.nodes.len());

๐Ÿ” Visitor Pattern

use typescript_ir::{Visitor, Expression, Statement, Program};

/// Custom visitor
struct MyVisitor {
    result: Vec<String>,
}

impl Visitor<()> for MyVisitor {
    fn visit_expression(&mut self, expr: &Expression) {
        match expr {
            Expression::Identifier(name) => {
                self.result.push(format!("Found identifier: {}", name));
            }
            _ => {}
        }
    }
    
    fn visit_statement(&mut self, stmt: &Statement) {
        // Handle statements...
    }
    
    fn visit_program(&mut self, program: &Program) {
        for stmt in &program.statements {
            self.visit_statement(stmt);
        }
    }
    
    // ... other methods
}

๐Ÿงช Testing

# Run all tests
cargo test --package typescript-ir

# Run optimization tests
cargo test --package typescript-ir -- optimization

# View output
cargo test --package typescript-ir -- --nocapture

๐Ÿ“š Dependencies

  • typescript-types - Type definitions
  • oak-typescript - AST definitions (re-export)
  • serde - Serialization support

๐Ÿค Contributing

We welcome issues and PRs! Please ensure:

  1. โœ… Code passes cargo clippy checks
  2. โœ… Code is formatted with cargo fmt
  3. โœ… All tests pass with cargo test
  4. โœ… New features include corresponding tests

๐Ÿ“„ License

MIT License - see LICENSE


๐Ÿฆ€ Intermediate representation, the bridge between compilation ๐Ÿ”„

Dependencies

~0.3โ€“1MB
~20K SLoC