Skip to content

Commit f308375

Browse files
authored
Add CUDA as one of the targets and update language server to support it (#149)
* Add CUDA as one of the targets and update language server to support it * Update CUDA syntax highlighting
1 parent a43357d commit f308375

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

src/App.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const compileTargets = [
2929
"GLSL",
3030
"METAL",
3131
"WGSL",
32+
"CUDA",
3233
] as const
3334
const targetProfileMap: { [target in typeof compileTargets[number]]?: { default: string, options: string[] } } = {
3435
// TODO: uncomment when we support specifying profiles.
@@ -41,6 +42,7 @@ const targetLanguageMap: { [target in typeof compileTargets[number]]: string } =
4142
"GLSL": "generic-shader",
4243
"METAL": "generic-shader",
4344
"WGSL": "wgsl",
45+
"CUDA": "cuda",
4446
};
4547
4648
const codeEditor = useTemplateRef("codeEditor");

src/language-server.ts

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,172 @@ export function initMonaco() {
685685
};
686686
}
687687
});
688+
689+
monaco.languages.register({ id: "cuda" });
690+
monaco.languages.setMonarchTokensProvider("cuda", {
691+
// Keywords and Identifiers
692+
cudaQualifiers: [
693+
'__global__', '__device__', '__host__', '__noinline__', '__forceinline__', '__launch_bounds__',
694+
],
695+
cudaStorageModifiers: [
696+
'__constant__', '__managed__', '__shared__', '__restrict__',
697+
],
698+
cudaBuiltinVars: [
699+
'gridDim', 'blockIdx', 'blockDim', 'threadIdx', 'warpSize',
700+
],
701+
// A selection of common CUDA library functions. A more comprehensive list can be added.
702+
cudaLibFunctions: [
703+
'cudaMalloc', 'cudaFree', 'cudaMemcpy', 'cudaMemset', 'cudaMallocManaged',
704+
'atomicAdd', 'atomicExch', 'atomicSub', 'atomicMin', 'atomicMax', 'atomicInc', 'atomicDec', 'atomicCAS',
705+
'atomicAnd', 'atomicOr', 'atomicXor',
706+
'__shfl', '__shfl_sync', '__shfl_up_sync', '__shfl_down_sync', '__shfl_xor_sync', // Sync variants are common
707+
'__ballot', '__ballot_sync', '__all', '__all_sync', '__any', '__any_sync',
708+
'__syncthreads', '__syncthreads_count', '__syncthreads_and', '__syncthreads_or',
709+
'__threadfence', '__threadfence_block', '__threadfence_system',
710+
'clock', 'clock64', 'printf',
711+
// Common math functions (often prefixed with __ in device code)
712+
'__sinf', '__cosf', '__tanf', '__expf', '__logf', '__log2f', '__log10f',
713+
'__sqrtf', '__rsqrtf', '__powf', '__fmaf', '__fma',
714+
'__saturatef', 'abs', 'min', 'max', 'ldg', 'tex1Dfetch', 'tex1D', 'tex2D', 'tex3D',
715+
// Surface functions
716+
'surf1Dread', 'surf2Dread', 'surf3Dread', 'surf1Dwrite', 'surf2Dwrite', 'surf3Dwrite',
717+
],
718+
cppKeywords: [
719+
'alignas', 'alignof', 'asm', 'auto', 'break', 'case', 'catch', 'class', 'const', 'constexpr', 'const_cast',
720+
'continue', 'decltype', 'default', 'delete', 'do', 'dynamic_cast',
721+
'else', 'enum', 'explicit', 'export', 'extern', 'false', 'final', 'for', 'friend',
722+
'goto', 'if', 'inline', 'mutable', 'namespace', 'new', 'noexcept', 'nullptr',
723+
'operator', 'override', 'private', 'protected', 'public', 'register', 'reinterpret_cast',
724+
'return', 'sizeof', 'static', 'static_assert', 'static_cast', 'struct',
725+
'switch', 'template', 'this', 'thread_local', 'throw', 'true', 'try', 'typedef',
726+
'typeid', 'typename', 'union', 'using', 'virtual', 'volatile', 'while',
727+
// C keywords often used
728+
'restrict', '_Atomic', '_Bool', '_Complex', '_Generic', '_Imaginary',
729+
'_Noreturn', '_Static_assert', '_Thread_local'
730+
],
731+
storageTypes: [ // Basic C++/CUDA types
732+
'bool', 'char', 'char16_t', 'char32_t', 'double', 'float', 'int', 'long', 'short',
733+
'signed', 'unsigned', 'void', 'wchar_t', 'half', 'half2', // CUDA half types
734+
],
735+
typedefVariables: [ // Common typedefs including from CUDA
736+
"size_t", "ptrdiff_t", "wchar_t", "nullptr_t",
737+
"cudaError_t", "cudaStream_t", "cudaEvent_t", "dim3" // dim3 is struct but often used like a typedef
738+
],
739+
740+
operators: [
741+
'=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=',
742+
'&&', '||', '++', '--', '+', '-', '*', '/', '&', '|', '^', '%',
743+
'<<', '>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=',
744+
'%=', '<<=', '>>=', '->', '.', '...', // Added ellipsis for varargs
745+
],
746+
747+
symbols: /[=><!~?:&|+\-*\/\^%.]+/, // Added dot to symbols as it can be an operator
748+
749+
escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
750+
751+
brackets: [
752+
{ open: '{', close: '}', token: 'delimiter.curly' },
753+
{ open: '[', close: ']', token: 'delimiter.square' },
754+
{ open: '(', close: ')', token: 'delimiter.parenthesis' },
755+
{ open: '<', close: '>', token: 'delimiter.angle' }
756+
],
757+
758+
tokenizer: {
759+
root: [
760+
{ include: '@whitespace' },
761+
{ include: '@comments' },
762+
{ include: '@preprocessor' },
763+
764+
// CUDA Kernel Launch Syntax
765+
[/<<<</, 'keyword.control.cuda.kernel-launch'],
766+
[/>>>/, 'keyword.control.cuda.kernel-launch'],
767+
768+
// CUDA vector types like float4, int2, etc. (e.g., int1, float2, uchar4)
769+
[/\b((?:u?(?:char|short|int|long|longlong))|float|double)[1-4]\b/, 'type.cuda.vector'],
770+
// dim3 is handled by typedefVariables or as a struct by cppKeywords
771+
772+
// Identifiers, keywords, library functions
773+
[/[a-zA-Z_]\w*/, {
774+
cases: {
775+
'@cudaLibFunctions': 'support.function.cuda',
776+
'@cudaQualifiers': 'keyword.qualifier.cuda',
777+
'@cudaStorageModifiers': 'storage.modifier.cuda',
778+
'@cudaBuiltinVars': 'variable.language.cuda',
779+
'@typedefVariables': 'type.typedef',
780+
'@storageTypes': 'type',
781+
'@cppKeywords': 'keyword',
782+
'@default': 'identifier'
783+
}
784+
}],
785+
786+
// Numbers (covers C++20 digit separators ')
787+
[/\b\d*\.\d+([eE][\-+]?\d+)?[fFhH]?\b/, 'number.float'], // f/F for float, h/H for half
788+
[/\b0[xX][0-9a-fA-F](?:[0-9a-fA-F']*[0-9a-fA-F])?(?:[uUlL]{0,2})?\b/, 'number.hex'],
789+
[/\b0[bB][01](?:[01']*[01])?(?:[uUlL]{0,2})?\b/, 'number.binary'],
790+
[/\b\d(?:[\d']*\d)?(?:[uUlL]{0,2})?\b/, 'number'],
791+
792+
// Delimiters and Operators
793+
[/[{}()\[\]]/, '@brackets'],
794+
[/[<>](?!@symbols)/, '@brackets'], // Distinguish < > for templates/generics
795+
[/@symbols/, {
796+
cases: {
797+
'@operators': 'operator',
798+
'@default': ''
799+
}
800+
}],
801+
[/[;,~?:`]/, 'delimiter'], // Added backtick, tilde, colon, question mark
802+
803+
// Strings
804+
[/"([^"\\]|\\.)*$/, 'string.invalid'],
805+
[/"/, { token: 'string.quote', bracket: '@open', next: '@string_double' }],
806+
807+
// Characters
808+
[/'[^\\']'/, 'string.character'],
809+
[/(')(@escapes)(')/, ['string.character', 'constant.character.escape', 'string.character']],
810+
[/'/, 'string.invalid']
811+
],
812+
813+
whitespace: [
814+
[/[ \t\r\n]+/, ''], // Tokenize whitespace as empty to avoid default coloring
815+
],
816+
817+
comments: [
818+
[/\/\*/, 'comment', '@comment_block'],
819+
[/\/\/.*$/, 'comment.line'],
820+
],
821+
comment_block: [ // Changed state name for clarity
822+
[/[^\/*]+/, 'comment'],
823+
[/\*\//, 'comment', '@pop'],
824+
[/[\/*]/, 'comment']
825+
],
826+
827+
string_double: [ // Changed state name for clarity
828+
[/[^\\"]+/, 'string'],
829+
[/@escapes/, 'constant.character.escape'],
830+
[/\\./, 'string.escape.invalid'],
831+
[/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }]
832+
],
833+
834+
preprocessor: [
835+
[/^\s*#\s*include/, { token: 'keyword.control.directive.include', next: '@include_path'}],
836+
[/^\s*#\s*(define|undef|if|ifdef|ifndef|else|elif|endif|line|error|pragma|warning)\b/, 'keyword.control.directive.cpp'],
837+
],
838+
include_path: [ // Changed state name for clarity
839+
// Matches <path/to/header.h> or "path/to/header.h"
840+
[/\s*"/, { token: 'string.include.identifier.quoted', next: '@include_path_body_quoted', bracket: '@open'}],
841+
[/\s*</, { token: 'string.include.identifier.angled', next: '@include_path_body_angled', bracket: '@open'}],
842+
[/./, '', '@pop'], // Fallback if no path follows
843+
],
844+
include_path_body_quoted: [
845+
[/[^"]+/, 'string.include.identifier.quoted'],
846+
[/"/, {token: 'string.include.identifier.quoted', next: '@pop', bracket: '@close'}],
847+
],
848+
include_path_body_angled: [
849+
[/[^>]+/, 'string.include.identifier.angled'],
850+
[/>/, {token: 'string.include.identifier.angled', next: '@pop', bracket: '@close'}],
851+
],
852+
}
853+
});
688854
}
689855

690856
export function initLanguageServer() {

0 commit comments

Comments
 (0)