From 59650aab5b023741da91838c9009efc18e62fb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Delahaye?= Date: Sun, 19 Oct 2014 00:41:06 +0200 Subject: [PATCH] Fix OCaml language support Various improvements: - character support - type variable - polymorphic variant tag - module name/variant constructor - support ' in identifier - add support for literals () [] [||] - better support for numbers - remove unrelated rules (from F# maybe?) - add new ! keywords - cleanup built-in types A step backward: remove very incomplete type definition matching Add tests B) --- docs/css-classes-reference.rst | 9 ++-- src/languages/ocaml.js | 66 ++++++++++++++++++--------- test/markup/ocaml/literals.expect.txt | 29 ++++++++++++ test/markup/ocaml/literals.txt | 29 ++++++++++++ test/markup/ocaml/types.expect.txt | 17 +++++++ test/markup/ocaml/types.txt | 17 +++++++ 6 files changed, 142 insertions(+), 25 deletions(-) create mode 100644 test/markup/ocaml/literals.expect.txt create mode 100644 test/markup/ocaml/literals.txt create mode 100644 test/markup/ocaml/types.expect.txt create mode 100644 test/markup/ocaml/types.txt diff --git a/docs/css-classes-reference.rst b/docs/css-classes-reference.rst index 7ffd385b6c..357250fd4f 100644 --- a/docs/css-classes-reference.rst +++ b/docs/css-classes-reference.rst @@ -654,12 +654,15 @@ OCaml ("ocaml", "ml") --------------------- * ``keywords``: keyword +* ``literal``: true false etc. * ``number``: number * ``string``: string +* ``char``: character * ``comment``: comment -* ``class``: any custom OCaml type -* ``title``: the name of a custom OCaml type -* ``annotation``: any attribute +* ``built_in``: built-in type (int, list etc.) +* ``type``: variant constructor, module name +* ``tag``: polymorphic variant tag +* ``symbol``: type variable D ("d") ------- diff --git a/src/languages/ocaml.js b/src/languages/ocaml.js index da70645525..192191cf01 100644 --- a/src/languages/ocaml.js +++ b/src/languages/ocaml.js @@ -1,49 +1,71 @@ /* Language: OCaml Author: Mehdi Dogguy -Contributors: Nicolas Braud-Santoni +Contributors: Nicolas Braud-Santoni , Mickael Delahaye Description: OCaml language definition. */ function(hljs) { + /* missing support for heredoc-like string (OCaml 4.0.2+) */ return { aliases: ['ml'], keywords: { keyword: '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 object of open or private rec ref sig struct ' + - 'then to true try type val virtual when while with parser value', + 'exception external for fun function functor if in include ' + + 'inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method ' + + 'mod module|5 mutable|5 new object of open! open or private rec sig|5 struct ' + + 'then to try type val! val virtual when while with ' + + /* camlp4 */ + 'parser value', built_in: - 'bool char float int list unit array exn option int32 int64 nativeint ' + - 'format4 format6 lazy_t in_channel out_channel string' + /* built-in types */ + 'array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit ' + + /* (some) types in Pervasives */ + 'in_channel out_channel ref', + literal: + 'true false', }, illegal: /\/\//, + lexemes: '[a-z_]\\w*!?', contains: [ { - className: 'string', - begin: '"""', end: '"""' + className: 'literal', + begin: '\\[(\\|\\|)?\\]|\\(\\)' }, { className: 'comment', begin: '\\(\\*', end: '\\*\\)', - contains: ['self'] + contains: ['self'], }, - { - className: 'class', - beginKeywords: 'type', end: '\\(|=|$', excludeEnd: true, - contains: [ - hljs.UNDERSCORE_TITLE_MODE - ] + { /* type variable */ + className: 'symbol', + begin: '\'[A-Za-z_](?!\')[\\w\']*', + /* the grammar is ambiguous on how 'a'b should be interpreted but not the compiler */ }, - { - className: 'annotation', - begin: '\\[<', end: '>\\]' + { /* polymorphic variant */ + className: 'tag', + begin: '`[A-Z][\\w\']*', + }, + { /* module or constructor */ + className: 'type', + begin: '\\b[A-Z][\\w\']*', + relevance: 0 }, - hljs.C_BLOCK_COMMENT_MODE, - hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}), + { /* don't color identifiers, but safely catch all identifiers with '*/ + begin: '[a-z_]\\w*\'[\\w\']*', + relevance: 0 + }, + hljs.inherit(hljs.APOS_STRING_MODE, {className: 'char', relevance: 0}), hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}), - hljs.C_NUMBER_MODE + { + className: 'number', + begin: + '\\b(0[xX][a-fA-F0-9_]+[Lln]?|' + + '0[oO][0-7_]+[Lln]?|' + + '0[bB][01_]+[Lln]?|' + + '[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)', + relevance: 0 + } ] } } diff --git a/test/markup/ocaml/literals.expect.txt b/test/markup/ocaml/literals.expect.txt new file mode 100644 index 0000000000..6155e8f6a4 --- /dev/null +++ b/test/markup/ocaml/literals.expect.txt @@ -0,0 +1,29 @@ +let i = 14 +let i = -14 +let i = 1_000 +let i = 0b100 +let i = 0x1FF +let i = 0o777 +let i64 = 128L +let i64 = 0b10L +let i32 = 32l +let i32 = 0x12l +let nat = 10n +let nat = 0o644n +let f = 5. +let f = 5.1 +let f = 1e+1 +let f = 1e1 +let f = 1e-1 +let f = 1_024e12 +let f = 1L + +let b = true || false +let l = [] +let a = [||] +let () = ignore (b) + +let c = 'a' +let c = '\xFF' +let c = '\128' +let c = '\n' diff --git a/test/markup/ocaml/literals.txt b/test/markup/ocaml/literals.txt new file mode 100644 index 0000000000..d9d3632c17 --- /dev/null +++ b/test/markup/ocaml/literals.txt @@ -0,0 +1,29 @@ +let i = 14 +let i = -14 +let i = 1_000 +let i = 0b100 +let i = 0x1FF +let i = 0o777 +let i64 = 128L +let i64 = 0b10L +let i32 = 32l +let i32 = 0x12l +let nat = 10n +let nat = 0o644n +let f = 5. +let f = 5.1 +let f = 1e+1 +let f = 1e1 +let f = 1e-1 +let f = 1_024e12 +let f = 1L + +let b = true || false +let l = [] +let a = [||] +let () = ignore (b) + +let c = 'a' +let c = '\xFF' +let c = '\128' +let c = '\n' diff --git a/test/markup/ocaml/types.expect.txt b/test/markup/ocaml/types.expect.txt new file mode 100644 index 0000000000..e0cc7c712d --- /dev/null +++ b/test/markup/ocaml/types.expect.txt @@ -0,0 +1,17 @@ +(* type variables *) +type 'a t = 'a list +let f (a : 'a list) : 'a = List.hd a + +(* polymorphic variants *) +type t = [ `A | `B ] + +(* variants *) +type result = Sat | Unsat | Unknown + +(* module and module types *) +module type S = sig + val compute : unit -> unit +end +module Impl : S = struct + let compute () = () +end diff --git a/test/markup/ocaml/types.txt b/test/markup/ocaml/types.txt new file mode 100644 index 0000000000..c18ed561e2 --- /dev/null +++ b/test/markup/ocaml/types.txt @@ -0,0 +1,17 @@ +(* type variables *) +type 'a t = 'a list +let f (a : 'a list) : 'a = List.hd a + +(* polymorphic variants *) +type t = [ `A | `B ] + +(* variants *) +type result = Sat | Unsat | Unknown + +(* module and module types *) +module type S = sig + val compute : unit -> unit +end +module Impl : S = struct + let compute () = () +end