Ralph Wittig

17 papers A* 1A 1B 1Misc 1Journal 5Unranked 8
YearRankTypeTitle / Venue / Authors
2024 J jnl
IEEE Micro
Krishnakumar Nair, Avinash-Chandra Pandey, Siddappa Karabannavar, Meena Arunachalam, John Kalamatianos, Varun Agrawal, Saurabh Gupta, Ashish Sirasao, Elliott Delaye, Steven K. Reinhardt, Rajesh Vivekanandham, Ralph Wittig, Vinod Kathail, Padmini Gopalakrishnan, Satyaprakash Pareek, Rishabh Jain, Mahmut Taylan Kandemir, Jun-Liang Lin, Gulsum Gudukbay Akbulut, Chita R. Das
2023 J jnl
CoRR
Bita Darvish Rouhani, Ritchie Zhao, Ankit More, Mathew Hall, Alireza Khodamoradi, Summer Deng, Dhruv Choudhary, Marius Cornea, Eric Dellinger, Kristof Denolf, Dusan Stosic, Venmugil Elango, Maximilian Golub, Alexander Heinecke, Phil James-Roxby, Dharmesh Jani, Gaurav Kolhe, Martin Langhammer, Ada Li, Levi Melnick, Maral Mesmakhosroshahi, Andres Rodriguez, Michael Schulte, Rasoul Shafipour, Lei Shao, Michael Y. Siu, Pradeep Dubey, Paulius Micikevicius, Maxim Naumov, Colin Verilli, Ralph Wittig, Doug Burger, Eric S. Chung
2020 conf
Hot Chips Symposium
Martin Voogel, Yohan Frans, Matt Ouellette, Jason Coppens, Sagheer Ahmad, Jaideep Dastidar, Ehab Mohsen, Faisal Dada, Mike Thompson, Ralph Wittig, Trevor Bauer, Gaurav Singh
2019 conf
Hot Chips Symposium
Sagheer Ahmad, Sridhar Subramanian, Vamsi Boppana, Shankar Lakka, Fu-Hing Ho, Tomai Knopp, Juanjo Noguera, Gaurav Singh, Ralph Wittig
2016 J jnl
IEEE Micro
Sagheer Ahmad, Vamsi Boppana, Ilya Ganusov, Vinod Kathail, Vidya Rajagopalan, Ralph Wittig
2015 conf
FPT
Jasmina Vasiljevic, Ralph Wittig, Paul Schumacher, Jeff Fifield, Fernando Martinez-Vallina, Henry Styles, Paul Chow
2015 conf
Hot Chips Symposium
Vamsi Boppana, Sagheer Ahmad, Ilya Ganusov, Vinod Kathail, Vidya Rajagopalan, Ralph Wittig
2011 conf
Hot Chips Symposium
Vidya Rajagopalan, Vamsi Boppana, Sandeep Dutta, Brad Taylor, Ralph Wittig
2010 conf
Hot Chips Symposium
Brad Taylor, Ralph Wittig
2010 J jnl
IEEE Micro
Krste Asanovic, Ralph Wittig
2010 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Manuel Saldaña, Arun Patel, Christopher A. Madill, Daniel Nunes, Danyao Wang, Paul Chow, Ralph Wittig, Henry Styles, Andrew Putnam
2009 A conf
FPGA
Andrew Putnam, Susan J. Eggers, Dave Bennett, Eric Dellinger, Jeff Mason, Henry Styles, Prasanna Sundararajan, Ralph Wittig
2009 A* conf
ISCA
Andrew Putnam, Susan J. Eggers, Dave Bennett, Eric Dellinger, Jeff Mason, Henry Styles, Prasanna Sundararajan, Ralph Wittig
2008 conf
HPRCTA@SC
Dave Strenski, Jim Simkins, Richard Walke, Ralph Wittig
2008 conf
HPRCTA@SC
Manuel Saldaña, Arun Patel, Christopher A. Madill, Daniel Nunes, Danyao Wang, Henry Styles, Andrew Putnam, Ralph Wittig, Paul Chow
1998 B conf
FPL
James Hwang, Cameron Patterson, S. Mohan, Eric Dellinger, Sujoy Mitra, Ralph Wittig
1996 Misc conf
FCCM
Ralph Wittig, Paul Chow
src/highlight.rs
← Index src/highlight.rs rust
use once_cell::sync::Lazy;
use regex::Regex;
use std::collections::HashMap;

/// Highlighting rules for a "family" of languages.
struct LangRule {
    line_comments: &'static [&'static str],
    block_comments: &'static [(&'static str, &'static str)],
    /// If true, enables strings delimited by " and '
    strings: bool,
    /// If true, also enables triple-quoted strings (Python)
    triple_quote: bool,
    /// If true, also enables backtick template strings (JS/TS)
    backtick: bool,
    /// If true, keywords are matched case-insensitively (e.g. SQL)
    case_insensitive_keywords: bool,
    keywords: &'static [&'static str],
}

const EMPTY_KW: &[&str] = &[];

fn rule_for(lang: &str) -> LangRule {
    match lang {
        "rust" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "as", "break", "const", "continue", "crate", "dyn", "else", "enum", "extern",
                "false", "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod", "move",
                "mut", "pub", "ref", "return", "self", "Self", "static", "struct", "super",
                "trait", "true", "type", "unsafe", "use", "where", "while", "async", "await",
                "union",
            ],
        },
        "python" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: true,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "False", "None", "True", "and", "as", "assert", "async", "await", "break",
                "class", "continue", "def", "del", "elif", "else", "except", "finally", "for",
                "from", "global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or",
                "pass", "raise", "return", "try", "while", "with", "yield", "self",
            ],
        },
        "javascript" | "typescript" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: true,
            case_insensitive_keywords: false,
            keywords: &[
                "break", "case", "catch", "class", "const", "continue", "debugger", "default",
                "delete", "do", "else", "export", "extends", "finally", "for", "function", "if",
                "import", "in", "instanceof", "new", "return", "super", "switch", "this", "throw",
                "try", "typeof", "var", "void", "while", "with", "yield", "let", "static",
                "async", "await", "of", "null", "true", "false", "undefined", "interface",
                "type", "enum", "implements", "namespace", "readonly", "public", "private",
                "protected", "abstract", "as", "declare", "from", "get", "set",
            ],
        },
        "java" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char",
                "class", "const", "continue", "default", "do", "double", "else", "enum",
                "extends", "final", "finally", "float", "for", "goto", "if", "implements",
                "import", "instanceof", "int", "interface", "long", "native", "new", "package",
                "private", "protected", "public", "return", "short", "static", "strictfp",
                "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try",
                "void", "volatile", "while", "true", "false", "null", "var", "record", "yield",
                "sealed", "permits",
            ],
        },
        "c" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "auto", "break", "case", "char", "const", "continue", "default", "do", "double",
                "else", "enum", "extern", "float", "for", "goto", "if", "inline", "int", "long",
                "register", "restrict", "return", "short", "signed", "sizeof", "static",
                "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while",
            ],
        },
        "cpp" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "auto", "break", "case", "char", "const", "continue", "default", "do", "double",
                "else", "enum", "extern", "float", "for", "goto", "if", "inline", "int", "long",
                "register", "return", "short", "signed", "sizeof", "static", "struct", "switch",
                "typedef", "union", "unsigned", "void", "volatile", "while", "class",
                "namespace", "template", "typename", "public", "private", "protected", "virtual",
                "friend", "this", "new", "delete", "try", "catch", "throw", "using", "operator",
                "explicit", "mutable", "bool", "true", "false", "nullptr", "constexpr",
                "decltype", "noexcept", "override", "final",
            ],
        },
        "csharp" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char",
                "checked", "class", "const", "continue", "decimal", "default", "delegate", "do",
                "double", "else", "enum", "event", "explicit", "extern", "false", "finally",
                "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int",
                "interface", "internal", "is", "lock", "long", "namespace", "new", "null",
                "object", "operator", "out", "override", "params", "private", "protected",
                "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof",
                "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true",
                "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using",
                "virtual", "void", "volatile", "while", "var", "async", "await", "yield",
                "nameof",
            ],
        },
        "go" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: true,
            case_insensitive_keywords: false,
            keywords: &[
                "break", "case", "chan", "const", "continue", "default", "defer", "else",
                "fallthrough", "for", "func", "go", "goto", "if", "import", "interface", "map",
                "package", "range", "return", "select", "struct", "switch", "type", "var",
                "true", "false", "nil", "iota",
            ],
        },
        "ruby" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "def", "end", "if", "elsif", "else", "unless", "while", "until", "for", "in",
                "do", "begin", "rescue", "ensure", "raise", "class", "module", "self", "nil",
                "true", "false", "and", "or", "not", "then", "yield", "return", "break", "next",
                "redo", "retry", "super", "require", "require_relative", "attr_accessor",
                "attr_reader", "attr_writer", "private", "public", "protected",
            ],
        },
        "php" => LangRule {
            line_comments: &["//", "#"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class",
                "clone", "const", "continue", "declare", "default", "do", "echo", "else",
                "elseif", "empty", "extends", "final", "finally", "fn", "for", "foreach",
                "function", "global", "goto", "if", "implements", "include", "include_once",
                "instanceof", "interface", "isset", "list", "match", "namespace", "new", "or",
                "print", "private", "protected", "public", "require", "require_once", "return",
                "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while",
                "xor", "yield", "true", "false", "null", "self", "parent",
            ],
        },
        "bash" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "if", "then", "else", "elif", "fi", "for", "while", "until", "do", "done",
                "case", "esac", "function", "in", "return", "break", "continue", "local",
                "export", "readonly", "shift", "exit", "echo", "source",
            ],
        },
        "sql" => LangRule {
            line_comments: &["--"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: true,
            keywords: &[
                "select", "from", "where", "insert", "into", "values", "update", "set",
                "delete", "create", "table", "alter", "drop", "join", "inner", "left", "right",
                "outer", "on", "group", "by", "order", "having", "as", "and", "or", "not",
                "null", "is", "in", "like", "limit", "offset", "distinct", "union", "all",
                "exists", "between", "case", "when", "then", "end", "primary", "key", "foreign",
                "references", "default", "index", "view", "trigger", "procedure", "function",
                "begin", "commit", "rollback",
            ],
        },
        "lua" => LangRule {
            line_comments: &["--"],
            block_comments: &[("--[[", "]]")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if",
                "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until",
                "while",
            ],
        },
        "kotlin" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "as", "break", "class", "continue", "do", "else", "false", "for", "fun", "if",
                "in", "interface", "is", "null", "object", "package", "return", "super", "this",
                "throw", "true", "try", "typealias", "val", "var", "when", "while", "by",
                "companion", "constructor", "data", "enum", "import", "init", "override",
                "private", "protected", "public", "sealed", "suspend",
            ],
        },
        "swift" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &[
                "class", "deinit", "enum", "extension", "func", "import", "init", "internal",
                "let", "operator", "private", "protocol", "public", "static", "struct",
                "subscript", "typealias", "var", "break", "case", "continue", "default", "do",
                "else", "fallthrough", "if", "in", "for", "return", "switch", "where", "while",
                "as", "false", "true", "guard", "nil", "self", "super", "throw", "try", "async",
                "await",
            ],
        },
        "css" | "scss" | "less" => LangRule {
            line_comments: &[],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: EMPTY_KW,
        },
        "xml" => LangRule {
            line_comments: &[],
            block_comments: &[("<!--", "-->")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: EMPTY_KW,
        },
        "json" => LangRule {
            line_comments: &[],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &["true", "false", "null"],
        },
        "yaml" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &["true", "false", "null", "yes", "no"],
        },
        "ini" => LangRule {
            line_comments: &["#", ";"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: EMPTY_KW,
        },
        "dockerfile" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: true,
            keywords: &[
                "from", "run", "cmd", "label", "expose", "env", "add", "copy", "entrypoint",
                "volume", "user", "workdir", "arg", "onbuild", "stopsignal", "healthcheck",
                "shell",
            ],
        },
        "makefile" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: EMPTY_KW,
        },
        "graphql" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &["query", "mutation", "subscription", "type", "input", "enum", "interface", "fragment", "on"],
        },
        // Language families without detailed specific rules: still
        // highlight comments/strings/numbers generically.
        "perl" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &["my", "our", "sub", "if", "elsif", "else", "unless", "while", "for", "foreach", "return", "use", "package"],
        },
        "groovy" => LangRule {
            line_comments: &["//"],
            block_comments: &[("/*", "*/")],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: EMPTY_KW,
        },
        "r" => LangRule {
            line_comments: &["#"],
            block_comments: &[],
            strings: true,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: &["function", "if", "else", "for", "while", "repeat", "break", "next", "return", "TRUE", "FALSE", "NULL", "NA"],
        },
        "diff" => LangRule {
            line_comments: &[],
            block_comments: &[],
            strings: false,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: EMPTY_KW,
        },
        // markdown, plaintext, cmake, vbnet, dos, powershell, etc:
        // no specific highlighting, plain but formatted text.
        _ => LangRule {
            line_comments: &[],
            block_comments: &[],
            strings: false,
            triple_quote: false,
            backtick: false,
            case_insensitive_keywords: false,
            keywords: EMPTY_KW,
        },
    }
}

/// Cache of compiled regexes (one per language actually encountered).
static REGEX_CACHE: Lazy<std::sync::Mutex<HashMap<String, Option<Regex>>>> =
    Lazy::new(|| std::sync::Mutex::new(HashMap::new()));

fn build_regex(rule: &LangRule) -> Option<Regex> {
    let mut comment_alts: Vec<String> = Vec::new();
    for (start, end) in rule.block_comments {
        comment_alts.push(format!(
            "(?s:{}.*?{})",
            regex::escape(start),
            regex::escape(end)
        ));
    }
    for prefix in rule.line_comments {
        comment_alts.push(format!("{}[^\n]*", regex::escape(prefix)));
    }

    let mut string_alts: Vec<String> = Vec::new();
    if rule.triple_quote {
        string_alts.push(r#"(?s:"""(?:[^"\\]|\\.)*?""")"#.to_string());
        string_alts.push(r#"(?s:'''(?:[^'\\]|\\.)*?''')"#.to_string());
    }
    if rule.strings {
        string_alts.push(r#""(?:[^"\\\n]|\\.)*""#.to_string());
        string_alts.push(r#"'(?:[^'\\\n]|\\.)*'"#.to_string());
    }
    if rule.backtick {
        string_alts.push(r"(?s:`(?:[^`\\]|\\.)*`)".to_string());
    }

    let number_pat = r"\b0[xX][0-9a-fA-F]+\b|\b\d+\.\d+(?:[eE][+-]?\d+)?\b|\b\d+\b".to_string();

    let mut keyword_alt = String::new();
    if !rule.keywords.is_empty() {
        let escaped: Vec<String> = rule.keywords.iter().map(|k| regex::escape(k)).collect();
        let joined = escaped.join("|");
        keyword_alt = if rule.case_insensitive_keywords {
            format!("(?i:\\b(?:{})\\b)", joined)
        } else {
            format!("\\b(?:{})\\b", joined)
        };
    }

    let mut parts: Vec<String> = Vec::new();
    if !comment_alts.is_empty() {
        parts.push(format!("(?P<comment>{})", comment_alts.join("|")));
    }
    if !string_alts.is_empty() {
        parts.push(format!("(?P<string>{})", string_alts.join("|")));
    }
    parts.push(format!("(?P<number>{})", number_pat));
    if !keyword_alt.is_empty() {
        parts.push(format!("(?P<keyword>{})", keyword_alt));
    }

    if parts.is_empty() {
        return None;
    }

    Regex::new(&parts.join("|")).ok()
}

fn escape_html(s: &str) -> String {
    let mut out = String::with_capacity(s.len());
    for c in s.chars() {
        match c {
            '&' => out.push_str("&amp;"),
            '<' => out.push_str("&lt;"),
            '>' => out.push_str("&gt;"),
            '"' => out.push_str("&quot;"),
            '\'' => out.push_str("&#39;"),
            _ => out.push(c),
        }
    }
    out
}

/// Highlights the source code and returns HTML that's already escaped
/// and ready to insert inside a `<pre><code>...</code></pre>`.
/// No JavaScript involved: all the work happens here, in Rust,
/// at file-generation time.
pub fn highlight_code(content: &str, lang: &str) -> String {
    let rule = rule_for(lang);

    let regex_opt = {
        let mut cache = REGEX_CACHE.lock().unwrap();
        cache
            .entry(lang.to_string())
            .or_insert_with(|| build_regex(&rule))
            .clone()
    };

    let Some(re) = regex_opt else {
        return escape_html(content);
    };

    let mut out = String::with_capacity(content.len() + content.len() / 4);
    let mut last = 0;

    for caps in re.captures_iter(content) {
        let m = caps.get(0).unwrap();
        out.push_str(&escape_html(&content[last..m.start()]));

        let class = if caps.name("comment").is_some() {
            "c"
        } else if caps.name("string").is_some() {
            "s"
        } else if caps.name("number").is_some() {
            "n"
        } else if caps.name("keyword").is_some() {
            "k"
        } else {
            ""
        };

        let escaped_match = escape_html(m.as_str());
        if class.is_empty() {
            out.push_str(&escaped_match);
        } else {
            out.push_str(&format!("<span class=\"{}\">{}</span>", class, escaped_match));
        }
        last = m.end();
    }
    out.push_str(&escape_html(&content[last..]));
    out
}