mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 07:04:04 -05:00
Add Mojo compiler (#7692)
This PR adds support for the Mojo programming language. Explicitly tested viewing the generated assembly, LLVM IR, and running the generated executable.
This commit is contained in:
7
.github/labeler.yml
vendored
7
.github/labeler.yml
vendored
@@ -260,6 +260,13 @@
|
||||
- 'etc/config/modula2.*.properties'
|
||||
- 'static/modes/modula2-mode.ts'
|
||||
|
||||
'lang-mojo':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'lib/compilers/mojo.ts'
|
||||
- 'etc/config/mojo.*.properties'
|
||||
- 'static/modes/mojo-mode.ts'
|
||||
|
||||
'lang-nim':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
|
||||
@@ -160,3 +160,4 @@ From oldest to newest contributor, we would like to thank:
|
||||
- [Mathias Gredal](https://github.com/mathiasgredal)
|
||||
- [RongDong Xu](https://github.com/arong)
|
||||
- [Adrien Bertrand](https://github.com/adriweb)
|
||||
- [Roberto Parolin](https://github.com/rparolin)
|
||||
|
||||
14
etc/config/mojo.amazon.properties
Normal file
14
etc/config/mojo.amazon.properties
Normal file
@@ -0,0 +1,14 @@
|
||||
compilers=&mojo
|
||||
mojo.defaultCompiler=mojo_25_3_0
|
||||
mojo.compilerType=mojo
|
||||
|
||||
group.mojo.compilers=mojo_25_3_0:mojo_nightly
|
||||
group.mojo.isSemVer=true
|
||||
group.mojo.baseName=Mojo
|
||||
|
||||
compiler.mojo_25_3_0.exe=/opt/compiler-explorer/mojo-25.3.0/bin/mojo
|
||||
compiler.mojo_25_3_0.semver=25.3.0
|
||||
|
||||
compiler.mojo_nightly.exe=/opt/compiler-explorer/mojo-nightly/bin/mojo
|
||||
compiler.mojo_nightly.semver=nightly
|
||||
compiler.mojo_nightly.isNightly=true
|
||||
9
etc/config/mojo.defaults.properties
Normal file
9
etc/config/mojo.defaults.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
compilers=&mojo
|
||||
mojo.defaultCompiler=mojo_nightly
|
||||
mojo.compilerType=mojo
|
||||
|
||||
group.mojo.compilers=mojo_nightly
|
||||
|
||||
supportsBinary=true
|
||||
supportsExecute=true
|
||||
supportsAsmDocs=true
|
||||
2
examples/mojo/default.mojo
Normal file
2
examples/mojo/default.mojo
Normal file
@@ -0,0 +1,2 @@
|
||||
fn square(n: Int) -> Int:
|
||||
return n * n
|
||||
@@ -103,6 +103,7 @@ export {LLVMMOSCompiler} from './llvm-mos.js';
|
||||
export {LLVMmcaTool} from './llvm-mca.js';
|
||||
export {MLIRCompiler} from './mlir.js';
|
||||
export {MadPascalCompiler} from './madpascal.js';
|
||||
export {MojoCompiler} from './mojo.js';
|
||||
export {MovfuscatorCompiler} from './movfuscator.js';
|
||||
export {MrustcCompiler} from './mrustc.js';
|
||||
export {Msp430Compiler} from './msp430.js';
|
||||
|
||||
@@ -604,6 +604,13 @@ export class PascalParser extends BaseParser {
|
||||
}
|
||||
}
|
||||
|
||||
export class MojoParser extends BaseParser {
|
||||
static override async parse(compiler: BaseCompiler) {
|
||||
await this.getOptions(compiler, '-help');
|
||||
return compiler;
|
||||
}
|
||||
}
|
||||
|
||||
export class ICCParser extends GCCParser {
|
||||
static override async setCompilerSettingsFromOptions(compiler: BaseCompiler, options: Record<string, Argument>) {
|
||||
const keys = _.keys(options);
|
||||
|
||||
59
lib/compilers/mojo.ts
Normal file
59
lib/compilers/mojo.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2025, Compiler Explorer Authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import path from 'node:path';
|
||||
import type {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces.js';
|
||||
import {BaseCompiler} from '../base-compiler.js';
|
||||
|
||||
export class MojoCompiler extends BaseCompiler {
|
||||
static get key() {
|
||||
return 'mojo';
|
||||
}
|
||||
|
||||
constructor(info, env) {
|
||||
super(info, env);
|
||||
this.delayCleanupTemp = true;
|
||||
this.compiler.supportsIrView = true;
|
||||
this.compiler.irArg = ['--emit=llvm'];
|
||||
}
|
||||
|
||||
override getOutputFilename(dirPath: string, inputFileBase: string) {
|
||||
// This method tells CE where to find the assembly output
|
||||
const outputPath = path.join(dirPath, 'example.s');
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions: string[]) {
|
||||
if (filters.binary) return ['build'];
|
||||
return ['build', '--emit=asm'];
|
||||
}
|
||||
|
||||
override getSharedLibraryPathsAsArguments() {
|
||||
return [];
|
||||
}
|
||||
|
||||
override getExecutableFilename(dirPath: string, outputFilebase: string) {
|
||||
return path.join(dirPath, 'example');
|
||||
}
|
||||
}
|
||||
@@ -591,6 +591,18 @@ const definitions: Record<LanguageKey, LanguageDefinition> = {
|
||||
previewFilter: null,
|
||||
monacoDisassembly: null,
|
||||
},
|
||||
mojo: {
|
||||
name: 'Mojo',
|
||||
monaco: 'mojo',
|
||||
extensions: ['.mojo', '.🔥'],
|
||||
alias: [],
|
||||
logoUrl: 'mojo.svg',
|
||||
logoUrlDark: null,
|
||||
formatter: 'mblack',
|
||||
previewFilter: null,
|
||||
monacoDisassembly: null,
|
||||
digitSeparator: '_',
|
||||
},
|
||||
nim: {
|
||||
name: 'Nim',
|
||||
monaco: 'nim',
|
||||
|
||||
@@ -54,6 +54,7 @@ import './jakt-mode';
|
||||
import './llvm-ir-mode';
|
||||
import './mlir-mode';
|
||||
import './modula2-mode';
|
||||
import './mojo-mode';
|
||||
import './nc-mode';
|
||||
import './nim-mode';
|
||||
import './nix-mode';
|
||||
|
||||
170
static/modes/mojo-mode.ts
Normal file
170
static/modes/mojo-mode.ts
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright (c) 2025, Compiler Explorer Authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import * as monaco from 'monaco-editor';
|
||||
|
||||
function definition(): monaco.languages.IMonarchLanguage {
|
||||
return {
|
||||
// Set defaultToken to invalid to see what you do not tokenize yet
|
||||
defaultToken: 'invalid',
|
||||
|
||||
// C# style strings
|
||||
escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
|
||||
|
||||
registers: /%?\b(r[0-9]+[dbw]?|([er]?([abcd][xhl]|cs|fs|ds|ss|sp|bp|ip|sil?|dil?))|[xyz]mm[0-9]+|sp|fp|lr)\b/,
|
||||
|
||||
intelOperators: /PTR|(D|Q|[XYZ]MM)?WORD/,
|
||||
|
||||
tokenizer: {
|
||||
root: [
|
||||
// Error document
|
||||
[/^<.*>$/, {token: 'annotation'}],
|
||||
// inline comments
|
||||
[/\/\*/, 'comment', '@comment'],
|
||||
// Label definition (anything looking like a label, followed by anything that's not valid in a demangled
|
||||
// identifier, until we get to a colon followed by any whitespace. This is to avoid finding the colon in
|
||||
// a scoped (blah::foo) identifier.
|
||||
[/^[.a-zA-Z0-9_$?@][^#;/]*:(?=\s)/, {token: 'type.identifier'}],
|
||||
// Label definition (quoted)
|
||||
[/^"([^"\\]|\\.)*":/, {token: 'type.identifier'}],
|
||||
// Label definition (ARM style)
|
||||
[/^\s*[|][^|]*[|]/, {token: 'type.identifier'}],
|
||||
// Label definition (CL style). This is pretty hideous: we essentially take anything that ends in spaces
|
||||
// followed by a definition (PROC, ENDP etc) and assume it's a label. That means we have to use
|
||||
// backtracking and then a lookahead to ensure we don't consume the definition. As a nod to efficiency
|
||||
// we assume the line has to start with a non-whitespace character before we go all back-tracky.
|
||||
// See https://github.com/compiler-explorer/compiler-explorer/issues/1645 for examples.
|
||||
[/^\S.*?(?=\s+(PROC|ENDP|D[BDWQ]))/, {token: 'type.identifier', next: '@rest'}],
|
||||
// Constant definition
|
||||
[/^[.a-zA-Z0-9_$?@][^=]*=/, {token: 'type.identifier'}],
|
||||
// opcode
|
||||
[/[.a-zA-Z_][.a-zA-Z_0-9]*/, {token: 'keyword', next: '@rest'}],
|
||||
// braces and parentheses at the start of the line (e.g. nvcc output)
|
||||
[/[(){}]/, {token: 'operator', next: '@rest'}],
|
||||
// msvc can have strings at the start of a line in a inSegDirList
|
||||
[/`/, {token: 'string.backtick', bracket: '@open', next: '@segDirMsvcstring'}],
|
||||
|
||||
// whitespace
|
||||
{include: '@whitespace'},
|
||||
],
|
||||
|
||||
rest: [
|
||||
// pop at the beginning of the next line and rematch
|
||||
[/^.*$/, {token: '@rematch', next: '@pop'}],
|
||||
|
||||
[/@registers/, 'variable.predefined'],
|
||||
[/@intelOperators/, 'annotation'],
|
||||
// inline comments
|
||||
[/\/\*/, 'comment', '@comment'],
|
||||
// CL style post-label definition.
|
||||
[/PROC|ENDP|D[BDWQ]/, 'keyword'],
|
||||
|
||||
// brackets
|
||||
[/[{}<>()[\]]/, '@brackets'],
|
||||
|
||||
// ARM-style label reference
|
||||
[/[|][^|]*[|]*/, 'type.identifier'],
|
||||
|
||||
// numbers
|
||||
[/\d*\.\d+([eE][-+]?\d+)?/, 'number.float'],
|
||||
[/([$]|0[xX])[0-9a-fA-F]+/, 'number.hex'],
|
||||
[/\d+/, 'number'],
|
||||
// ARM-style immediate numbers (which otherwise look like comments)
|
||||
[/#-?\d+/, 'number'],
|
||||
|
||||
// operators
|
||||
[/[-+,*/!:&{}()]/, 'operator'],
|
||||
|
||||
// strings
|
||||
[/"([^"\\]|\\.)*$/, 'string.invalid'], // non-terminated string
|
||||
[/"/, {token: 'string.quote', bracket: '@open', next: '@string'}],
|
||||
// `msvc does this, sometimes'
|
||||
[/`/, {token: 'string.backtick', bracket: '@open', next: '@msvcstring'}],
|
||||
[/'/, {token: 'string.singlequote', bracket: '@open', next: '@sstring'}],
|
||||
|
||||
// characters
|
||||
[/'[^\\']'/, 'string'],
|
||||
[/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
|
||||
[/'/, 'string.invalid'],
|
||||
|
||||
// Assume anything else is a label reference. .NET uses ` in some identifiers
|
||||
[/%?[.?_$a-zA-Z@][.?_$a-zA-Z0-9@`]*/, 'type.identifier'],
|
||||
|
||||
// whitespace
|
||||
{include: '@whitespace'},
|
||||
],
|
||||
|
||||
comment: [
|
||||
[/[^/*]+/, 'comment'],
|
||||
[/\/\*/, 'comment', '@push'], // nested comment
|
||||
['\\*/', 'comment', '@pop'],
|
||||
[/[/*]/, 'comment'],
|
||||
],
|
||||
|
||||
string: [
|
||||
[/[^\\"]+/, 'string'],
|
||||
[/@escapes/, 'string.escape'],
|
||||
[/\\./, 'string.escape.invalid'],
|
||||
[/"/, {token: 'string.quote', bracket: '@close', next: '@pop'}],
|
||||
],
|
||||
|
||||
msvcstringCommon: [
|
||||
[/[^\\']+/, 'string'],
|
||||
[/@escapes/, 'string.escape'],
|
||||
[/''/, 'string.escape'], // ` isn't escaped but ' is escaped as ''
|
||||
[/\\./, 'string.escape.invalid'],
|
||||
],
|
||||
|
||||
msvcstring: [
|
||||
{include: '@msvcstringCommon'},
|
||||
[/'/, {token: 'string.backtick', bracket: '@close', next: '@pop'}],
|
||||
],
|
||||
|
||||
segDirMsvcstring: [
|
||||
{include: '@msvcstringCommon'},
|
||||
[/'/, {token: 'string.backtick', bracket: '@close', switchTo: '@rest'}],
|
||||
],
|
||||
|
||||
sstring: [
|
||||
[/[^\\']+/, 'string'],
|
||||
[/@escapes/, 'string.escape'],
|
||||
[/\\./, 'string.escape.invalid'],
|
||||
[/'/, {token: 'string.singlequote', bracket: '@close', next: '@pop'}],
|
||||
],
|
||||
|
||||
whitespace: [
|
||||
[/[ \t\r\n]+/, 'white'],
|
||||
[/\/\*/, 'comment', '@comment'],
|
||||
[/\/\/.*$/, 'comment'],
|
||||
[/[#;\\@].*$/, 'comment'],
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const def = definition();
|
||||
monaco.languages.register({id: 'mojo'});
|
||||
monaco.languages.setMonarchTokensProvider('mojo', def);
|
||||
|
||||
export default def;
|
||||
@@ -74,6 +74,7 @@ export type LanguageKey =
|
||||
| 'llvm_mir'
|
||||
| 'mlir'
|
||||
| 'modula2'
|
||||
| 'mojo'
|
||||
| 'nim'
|
||||
| 'nix'
|
||||
| 'numba'
|
||||
|
||||
35
views/resources/logos/mojo.svg
Normal file
35
views/resources/logos/mojo.svg
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1000 1000" style="enable-background:new 0 0 1000 1000;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FF4C1F;}
|
||||
.st1{fill:#FF9C45;}
|
||||
.st2{fill:#FFDD56;}
|
||||
.st3{fill:#FCFBCC;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M732.35,443.58c5.88,23.21-19.09,47.98-19.09,47.98s-45.53,30.15-36.72-99.1S481.18,136.31,481.18,136.31
|
||||
s1.17,12.32,0,97.52c-1.47,107.22-63.16,70.5-63.16,70.5c-61.69,66.1-55.99,215.28-55.99,215.28
|
||||
c-76.38,67.56-79.14-72.81-79.14-72.81s-145.41,146.88,10.28,304.04c0,0,22.83,22.77-13.64,15.54
|
||||
c-26.01-5.15-31.89-15.54-31.89-15.54s5,65.09,188.5,105.72c3.56,0.72,60.59,11.9,124.99-0.98
|
||||
c141.32-31.8,165.96-90.74,165.96-90.74s-2.99,5.32-26.44,7.71c-25.2,2.57-3.58-21.72-3.58-21.72
|
||||
C863.07,646.56,726.47,420.37,732.35,443.58z"/>
|
||||
<path class="st1" d="M672.03,658c33.05-51.77,7.71-90.33,7.71-90.33c-51.81,26.64-67.31,8.04-71.91-7.04
|
||||
c-1.82-5.97-2.13-12.31-1.08-18.46c33.52-196.45-96.61-302.55-93.34-276.32c0.99,7.93-0.37,18.34-2.77,29.03
|
||||
c-5.67,25.31-16.52,49.15-31.31,70.45c-20.37,29.34-57.18,92.27-77.18,186.92C373.52,687.74,290.9,589.7,290.9,589.7
|
||||
s-48.28,165.16,148.91,267.54c11.61,2.01,48.35,7.28,92.64,2.67c129.49-60.95,175.93-179.88,175.93-179.88
|
||||
S638.98,709.77,672.03,658z"/>
|
||||
<g>
|
||||
<path class="st2" d="M626.84,622.82c0.02-0.05,0.03-0.07,0.03-0.07L626.84,622.82z"/>
|
||||
<path class="st2" d="M626.84,622.82c-0.67,1.72-14.54,35.4-66.06,43.99c-52.87,8.81-29.74-175.25-29.74-175.25
|
||||
c-129.98,61.58-105.75,206.09-105.75,206.09s-20.76,20.03-47.37,0c-9.04-6.8,10.81,116.12,95.8,163.39
|
||||
c15.77,0.98,35.46,1.17,56.99-0.96c58.47-40.64,89.55-167.94,89.55-167.94l-26.82,16.56L626.84,622.82z"/>
|
||||
</g>
|
||||
<path class="st0" d="M253.45,428.88c0,0-7.62-66.62,29.51-96.05c5.8-4.6,9.71-8.33,12.57-15.16c2.33-5.55,5.94-14.37,4.18-20.97
|
||||
C295.31,280.17,349.28,371.6,253.45,428.88z"/>
|
||||
<path class="st3" d="M531.11,860.05c23.61-24.8,55.09-123.89,55.09-123.89s-6.82,20.3-32.31,17.63
|
||||
c-35.06-3.68-54.34-96.94-54.34-96.94s-29.13,79.31-35.25,91.06c-12.89,24.75-36.72,0-36.72,0c-6.3,40.32,43.98,98.08,58.41,113.7
|
||||
C499.36,861.98,514.7,861.69,531.11,860.05z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
Reference in New Issue
Block a user