Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 201 additions & 0 deletions src/languages/ruchy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
Language: Ruchy
Description: Ruchy is a systems programming language with built-in actor model support and functional programming features
Author: Ruchy Language Team
Website: https://ruchy-lang.org
Category: system
*/

export default function(hljs) {
// Keywords organized by category for better maintainability
const KEYWORDS = {
keyword: [
// Control flow
'if', 'else', 'match', 'case', 'for', 'while', 'loop', 'break', 'continue', 'return',
// Declarations
'fn', 'let', 'mut', 'const', 'static', 'struct', 'enum', 'trait', 'impl', 'type', 'mod', 'use',
// Modifiers
'pub', 'async', 'await', 'unsafe', 'extern', 'move', 'ref', 'box',
// Actor keywords (Ruchy-specific)
'actor', 'spawn', 'send',
// Special identifiers
'self', 'Self', 'super', 'crate', 'as', 'in', 'where'
].join(' '),

type: [
// Primitive types
'bool', 'char', 'str',
// Integer types
'i8', 'i16', 'i32', 'i64', 'i128', 'isize',
'u8', 'u16', 'u32', 'u64', 'u128', 'usize',
// Float types
'f32', 'f64',
// Standard library types
'String', 'Vec', 'HashMap', 'HashSet', 'Result', 'Option',
'Box', 'Rc', 'Arc'
].join(' '),

literal: 'true false Some None Ok Err'
};

const OPERATORS = {
className: 'operator',
variants: [
// Pipeline operator (Ruchy-specific)
{ begin: '>>' },
// Actor operators (Ruchy-specific)
{ begin: '<-|<\\?' },
// Regular operators
{ begin: '[=!<>+\\-*/%&|^~:?]+' },
{ begin: '\\.\\.=?' },
{ begin: '=>' },
{ begin: '->' },
{ begin: '::' }
]
};

const LIFETIME = {
className: 'symbol',
begin: '\'[a-z_]\\w*'
};

const FUNCTION_DEFINITION = {
className: 'function',
beginKeywords: 'fn',
end: '\\(',
excludeEnd: true,
contains: [hljs.UNDERSCORE_TITLE_MODE]
};

const ACTOR_DEFINITION = {
className: 'class',
beginKeywords: 'actor',
end: '\\{',
excludeEnd: true,
contains: [hljs.UNDERSCORE_TITLE_MODE]
};

const TYPE_DEFINITION = {
className: 'class',
beginKeywords: 'struct enum trait type',
end: '[\\{\\(;]',
excludeEnd: true,
contains: [hljs.UNDERSCORE_TITLE_MODE]
};

const MACRO_INVOCATION = {
className: 'built_in',
begin: '\\w+!'
};

const ATTRIBUTE = {
className: 'meta',
begin: '#!?\\[[^\\]]*\\]'
};

const NUMBER = {
className: 'number',
variants: [
// Binary literals
{ begin: '\\b0b[01_]+(?:[iu](?:8|16|32|64|128|size))?\\b' },
// Octal literals
{ begin: '\\b0o[0-7_]+(?:[iu](?:8|16|32|64|128|size))?\\b' },
// Hexadecimal literals
{ begin: '\\b0x[0-9a-fA-F_]+(?:[iu](?:8|16|32|64|128|size))?\\b' },
// Float literals
{ begin: '\\b\\d[\\d_]*\\.\\d[\\d_]*(?:[eE][+-]?\\d[\\d_]+)?(?:f32|f64)?\\b' },
{ begin: '\\b\\d[\\d_]*(?:[eE][+-]?\\d[\\d_]+)(?:f32|f64)?\\b' },
{ begin: '\\b\\d[\\d_]*(?:f32|f64)\\b' },
// Integer literals with type suffixes
{ begin: '\\b\\d[\\d_]*(?:[iu](?:8|16|32|64|128|size))?\\b' }
]
};

const RAW_STRING = {
className: 'string',
begin: 'r#*"',
end: '"#*',
contains: []
};

const STRING = {
className: 'string',
begin: '"',
end: '"',
contains: [
hljs.BACKSLASH_ESCAPE,
{
className: 'subst',
begin: '\\$\\{',
end: '\\}',
contains: []
}
]
};

const CHAR = {
className: 'string',
begin: '\'[^\']*\''
};

const COMMENT_DOC = {
className: 'comment',
variants: [
{ begin: '///', end: '$' },
{ begin: '/\\*\\*', end: '\\*/' }
],
contains: [
{
className: 'doctag',
begin: '@\\w+'
}
]
};

const COMMENT = {
className: 'comment',
variants: [
{ begin: '//', end: '$' },
{ begin: '/\\*', end: '\\*/' }
],
contains: [
{
className: 'keyword',
begin: '\\b(?:TODO|FIXME|NOTE|HACK|XXX|BUG|DEBT|WORKAROUND)\\b'
}
]
};

// Set up recursive references for string interpolation
STRING.contains[1].contains = [
hljs.UNDERSCORE_IDENT_MODE,
NUMBER,
OPERATORS
];

return {
name: 'Ruchy',
aliases: ['rhy'],
keywords: KEYWORDS,
illegal: '</',
contains: [
COMMENT_DOC,
COMMENT,
LIFETIME,
FUNCTION_DEFINITION,
ACTOR_DEFINITION,
TYPE_DEFINITION,
MACRO_INVOCATION,
ATTRIBUTE,
RAW_STRING,
STRING,
CHAR,
NUMBER,
OPERATORS,
{
className: 'punctuation',
begin: '[{}\\[\\];():]'
}
]
};
}
92 changes: 92 additions & 0 deletions test/detect/ruchy/default.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Ruchy language demonstration for highlight.js testing

/// Documentation comment for the MessageProcessor actor
/// This actor handles message processing with state management
actor MessageProcessor {
state: Vec<String>,
counter: i32,

fn new() -> Self {
Self {
state: Vec::new(),
counter: 0
}
}

fn handle(&mut self, message: String) -> String {
self.counter += 1;
self.state.push(message.clone());

// Pipeline operator demonstration
let result = message
>> |s| s.to_uppercase()
>> |s| format!("Processed #{}: {}", self.counter, s)
>> |s| s.trim().to_string();

result
}
}

struct Config {
name: String,
timeout: f64,
enabled: bool,
}

enum MessageType {
Text(String),
Binary(Vec<u8>),
Empty,
}

trait Processor {
fn process(&mut self, data: &str) -> Result<String, String>;
}

impl Processor for MessageProcessor {
fn process(&mut self, data: &str) -> Result<String, String> {
match data {
"" => Err("Empty input".to_string()),
s if s.len() > 1000 => Err("Input too large".to_string()),
_ => Ok(self.handle(data.to_string())),
}
}
}

#[async]
fn main() {
// Create and spawn an actor
let processor = spawn(MessageProcessor::new());

// Send messages using actor operators
processor <- "Hello".to_string();
processor <- "World".to_string();

// Ask for response
let response = processor <? "Status".to_string();
println!("Response: {}", response);

// Numeric literals demonstration
let binary = 0b1010_1010u8;
let hex = 0xFF_FF_FFu32;
let float = 3.14159f64;

// String interpolation
let message = "Result: ${response}, Binary: ${binary}";

// Pattern matching
let result = match MessageType::Text("hello".to_string()) {
MessageType::Text(s) => s.to_uppercase(),
MessageType::Binary(_) => "Binary data".to_string(),
MessageType::Empty => "No data".to_string(),
};

println!("{}", result);
}

// FIXME: This is a technical debt comment
// TODO: Implement error handling
/*
Multi-line comment with HACK keyword
DEBT: Refactor this code
*/
27 changes: 27 additions & 0 deletions test/markup/ruchy/default.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Actor model example
actor Counter {
let mut count: i32 = 0;

receive Increment(n) -> {
count += n;
println!("Count is now: {}", count);
}

receive GetCount -> count
}

fn main() {
let counter = spawn!(Counter);

counter <- Increment(5);
counter <- Increment(10);

let result = counter <? GetCount;

// Pipeline operator
data
>> validate
>> transform
>> persist
>> log_result;
}