diff --git a/etc/config/ocaml.amazon.properties b/etc/config/ocaml.amazon.properties new file mode 100644 index 000000000..376e3ca50 --- /dev/null +++ b/etc/config/ocaml.amazon.properties @@ -0,0 +1,20 @@ +compilers=&ocaml +defaultCompiler=ocaml4071flambda + +group.ocaml.compilers=ocaml4042:ocaml4061:ocaml4071:ocaml4071flambda +group.ocaml.isSemVer=true +group.ocaml.baseName=x86-64 ocamlopt + +compiler.ocaml4042.exe=/opt/compiler-explorer/ocaml-4.04.2/usr/bin/ocamlopt +compiler.ocaml4042.semver=4.04.2 +compiler.ocaml4061.exe=/opt/compiler-explorer/ocaml-4.06.1/usr/bin/ocamlopt +compiler.ocaml4061.semver=4.06.1 +compiler.ocaml4071.exe=/opt/compiler-explorer/ocaml-4.07.1/usr/bin/ocamlopt +compiler.ocaml4071.semver=4.07.1 +compiler.ocaml4071flambda.exe=/opt/compiler-explorer/ocaml-4.07.1+flambda/usr/bin/ocamlopt +compiler.ocaml4071flambda.semver=4.07.1+flambda + +################################# +################################# +# Installed libs (See c++.amazon.properties for a scheme of libs group) +libs= \ No newline at end of file diff --git a/etc/config/ocaml.defaults.properties b/etc/config/ocaml.defaults.properties new file mode 100644 index 000000000..961dca6db --- /dev/null +++ b/etc/config/ocaml.defaults.properties @@ -0,0 +1,9 @@ +compilers=/usr/bin/ocamlopt +supportsBinary=false +compilerType=ocaml + + +################################# +################################# +# Installed libs (See c++.amazon.properties for a scheme of libs group) +libs= diff --git a/examples/ocaml/default.ml b/examples/ocaml/default.ml new file mode 100644 index 000000000..07f89c72d --- /dev/null +++ b/examples/ocaml/default.ml @@ -0,0 +1 @@ +let square x = x * x diff --git a/examples/ocaml/max_array.ml b/examples/ocaml/max_array.ml new file mode 100644 index 000000000..c37d2bac8 --- /dev/null +++ b/examples/ocaml/max_array.ml @@ -0,0 +1,8 @@ +let max_array array = + let max = ref 0 in + for i = 0 to Array.length array do + let el = array.(i) in + if el > !max + then max := el; + done; + !max diff --git a/examples/ocaml/sum.ml b/examples/ocaml/sum.ml new file mode 100644 index 000000000..a7d962c5c --- /dev/null +++ b/examples/ocaml/sum.ml @@ -0,0 +1,5 @@ +let sum l = + let rec sum' acc = function + | [] -> acc + | x::tl -> sum' (acc + x) tl + in sum' 0 l diff --git a/lib/compilers/ocaml.js b/lib/compilers/ocaml.js new file mode 100644 index 000000000..eb53db37b --- /dev/null +++ b/lib/compilers/ocaml.js @@ -0,0 +1,40 @@ +// Copyright (c) 2018, Eugen Bulavin +// 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. + +"use strict"; + +const BaseCompiler = require('../base-compiler'), + path = require("path"); + +class OCamlCompiler extends BaseCompiler { + optionsForFilter() { + return ['-S', '-g']; + } + + getOutputFilename(dirPath) { + return path.join(dirPath, `${path.basename(this.compileFilename, this.lang.extensions[0])}.s`); + } +} + +module.exports = OCamlCompiler; diff --git a/lib/languages.js b/lib/languages.js index 8155267b5..a345909cc 100644 --- a/lib/languages.js +++ b/lib/languages.js @@ -101,6 +101,12 @@ const languages = { extensions: ['.hs', '.haskell'], alias: [] }, + ocaml: { + name: 'OCaml', + monaco: 'ocaml', + extensions: ['.ml', '.mli'], + alias: [] + }, swift: { name: 'Swift', monaco: 'swift', diff --git a/static/modes/ocaml-mode.js b/static/modes/ocaml-mode.js new file mode 100644 index 000000000..fd2e0fc19 --- /dev/null +++ b/static/modes/ocaml-mode.js @@ -0,0 +1,135 @@ +// Copyright (c) 2018, Eugen Bulavin +// 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. + +"use strict"; + +var monaco = require('../monaco'); + +function definition() { + return { + keywords: [ + 'and', + 'as', + 'assert', + 'asr', + 'begin', + 'class', + 'constraint', + 'do', + 'done', + 'downto', + 'else', + 'end', + 'exception', + 'external', + 'false', + 'for', + 'fun', + 'function', + 'functor', + 'if', + 'in', + 'include', + 'inherit', + 'initializer', + 'land', + 'lazy', + 'let', + 'lor', + 'lsl', + 'lsr', + 'lxor', + 'match', + 'method', + 'mod', + 'module', + 'mutable', + 'new', + 'nonrec', + 'object', + 'of', + 'open', + 'or', + 'private', + 'rec', + 'sig', + 'struct', + 'then', + 'to', + 'true', + 'try', + 'type', + 'val', + 'virtual', + 'when', + 'while', + 'with', + ], + + typeKeywords: [ + 'int', + 'int32', + 'int64', + 'bool', + 'char', + 'unit', + ], + + numbers: /-?[0-9.]/, + + tokenizer: { + root: [ + // identifiers and keywords + [/[a-z_$][\w$]*/, { + cases: { + '@typeKeywords': 'keyword', + '@keywords': 'keyword', + '@default': 'identifier' + } + }], + + { include: '@whitespace' }, + + [/@numbers/, 'number'], + + [/[+\-*/=<>$@]/, 'operators'], + + [/(")(.*)(")/, ['string', 'string', 'string']] + ], + + comment: [ + [/[^(*]+/, 'comment'], + [/\*\)/, 'comment', '@pop'], + ], + + whitespace: [ + [/[ \t\r\n]+/, 'white'], + [/\(\*/, 'comment', '@comment'], + ], + } + }; +} + +monaco.languages.register({id: 'ocaml'}); +monaco.languages.setMonarchTokensProvider('ocaml', definition()); diff --git a/static/panes/editor.js b/static/panes/editor.js index 825d6b9c2..cc079e6e8 100644 --- a/static/panes/editor.js +++ b/static/panes/editor.js @@ -39,6 +39,7 @@ require('../modes/rust-mode'); require('../modes/ispc-mode'); require('../modes/llvm-ir-mode'); require('../modes/haskell-mode'); +require('../modes/ocaml-mode'); require('../modes/clean-mode'); require('../modes/pascal-mode'); require('../modes/cuda-mode');