diff --git a/Makefile.in b/Makefile.in index a91f8cd88312f86b41a763f6e8e892faa809130b..002776e3ec68dc5e029e6477b682618ecbd5fcee 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1663,6 +1663,7 @@ TRYWHY3_FULL_PACK = \ alt-ergo-worker.js \ ace-builds/src-min-noconflict/ace.js \ ace-builds/src-min-noconflict/mode-why3.js \ + ace-builds/src-min-noconflict/mode-coma.js \ ace-builds/src-min-noconflict/mode-python.js \ ace-builds/src-min-noconflict/mode-c_cpp.js \ ace-builds/src-min-noconflict/theme-chrome.js @@ -1688,7 +1689,7 @@ src/trywhy3/why3_worker.js: src/trywhy3/why3_worker.byte src/trywhy3/trywhy3.con `find stdlib -name "*.mlw" -exec printf " --file=%s:/%s" {} {} ";"` \ +dynlink.js +toplevel.js $< -src/trywhy3/why3_worker.byte: $(WHY3CMA) $(PYTHONCMO) $(MICROCCMO) \ +src/trywhy3/why3_worker.byte: $(WHY3CMA) $(PYTHONCMO) $(MICROCCMO) $(COMACMO) \ $(addprefix src/trywhy3/, bindings.cmo worker_proto.cmo why3_worker.cmo) $(OCAMLFIND) ocamlc $(filter-out -thread,$(BFLAGS)) -package js_of_ocaml -o $@ -linkpkg $^ diff --git a/src/trywhy3/mode-coma.js b/src/trywhy3/mode-coma.js new file mode 100644 index 0000000000000000000000000000000000000000..d0012b46363fbd7a1f17c48b4c4766661610632e --- /dev/null +++ b/src/trywhy3/mode-coma.js @@ -0,0 +1,240 @@ +ace.define("ace/mode/coma_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var ComaHighlightRules = function() { + + // keep synchronized with src/parser/lexer.mll + var keywords = ( + "abstract|absurd|alias|any|as|assert|assume|at|axiom|" + + "begin|break|by|check|clone|coinductive|constant|continue|" + + "diverges|do|done|downto|" + + "else|end|ensures|epsilon|exception|exists|export|" + + "false|float|for|forall|fun|function|ghost|goal|" + + "if|import|in|inductive|invariant|label|lemma|let|" + + "match|meta|module|mutable|not|old|" + + "partial|predicate|private|pure|" + + "raise|raises|range|reads|rec|ref|requires|return|returns|" + + "scope|so|then|theory|to|true|try|type|use|val|variant|" + + "while|with|writes" + ); + + var builtinConstants = ("true|false"); + + var builtinFunctions = (""); + + var keywordMapper = this.createKeywordMapper({ + "variable.language": "this", + "keyword": keywords, + "constant.language": builtinConstants, + "support.function": builtinFunctions + }, "identifier"); + + var decimalInteger = "(?:(?:[1-9]\\d*)|(?:0))"; + var octInteger = "(?:0[oO]?[0-7]+)"; + var hexInteger = "(?:0[xX][\\dA-Fa-f]+)"; + var binInteger = "(?:0[bB][01]+)"; + var integer = "(?:" + decimalInteger + "|" + octInteger + "|" + hexInteger + "|" + binInteger + ")"; + + var exponent = "(?:[eE][+-]?\\d+)"; + var fraction = "(?:\\.\\d+)"; + var intPart = "(?:\\d+)"; + var pointFloat = "(?:(?:" + intPart + "?" + fraction + ")|(?:" + intPart + "\\.))"; + var exponentFloat = "(?:(?:" + pointFloat + "|" + intPart + ")" + exponent + ")"; + var floatNumber = "(?:" + exponentFloat + "|" + pointFloat + ")"; + + this.$rules = { + "start" : [ + { token : [ "paren.lparen", "text", "paren.rparen" ], + regex : "([(])([*])([)])" + }, + { //black magic from Rust mode to handle nested comments. + token : "comment.start", + regex : "\\(\\*", + stateName : "comment", + push : [ + { + token: 'comment.start', + regex : "\\(\\*", + push : 'comment' + }, + { + token: 'comment.end', + regex: "\\*\\)", + next: 'pop' + }, + { + defaultToken: 'comment' + } + ] + }, + { + token : "string", // single line + regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + }, + { + token : "string", // single char + regex : "'.'" + }, + { + token : "string", // " string + regex : '"', + next : "qstring" + }, + { + token : "constant.numeric", // float + regex : floatNumber + }, + { + token : "constant.numeric", // integer + regex : integer + "\\b" + }, + { + token : keywordMapper, + regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, + { + token : "keyword.operator", + regex : "&&|\\|\\||/\\\\|\\\\/|->|<->" + }, + { + token : "paren.lparen", + regex : "[[({]" + }, + { + token : "paren.rparen", + regex : "[\\])}]" + }, + { + token : "text", + regex : "\\s+" + } + ], + "qstring" : [ + { + token : "string", + regex : '"', + next : "start" + }, { + token : "string", + regex : '[^"]' + } + ] + }; + + this.normalizeRules(); +}; + +oop.inherits(ComaHighlightRules, TextHighlightRules); + +exports.ComaHighlightRules = ComaHighlightRules; +}); + +ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +var MatchingBraceOutdent = function() {}; + +(function() { + + this.checkOutdent = function(line, input) { + if (! /^\s+$/.test(line)) + return false; + + return /^\s*\}/.test(input); + }; + + this.autoOutdent = function(doc, row) { + var line = doc.getLine(row); + var match = line.match(/^(\s*\})/); + + if (!match) return 0; + + var column = match[1].length; + var openBracePos = doc.findMatchingBracket({row: row, column: column}); + + if (!openBracePos || openBracePos.row == row) return 0; + + var indent = this.$getIndent(doc.getLine(openBracePos.row)); + doc.replace(new Range(row, 0, row, column-1), indent); + }; + + this.$getIndent = function(line) { + return line.match(/^\s*/)[0]; + }; + +}).call(MatchingBraceOutdent.prototype); + +exports.MatchingBraceOutdent = MatchingBraceOutdent; +}); + +ace.define("ace/mode/coma",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/coma_highlight_rules","ace/mode/matching_brace_outdent","ace/range"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var ComaHighlightRules = require("./coma_highlight_rules").ComaHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var Range = require("../range").Range; + +var Mode = function() { + this.HighlightRules = ComaHighlightRules; + + this.$outdent = new MatchingBraceOutdent(); +}; +oop.inherits(Mode, TextMode); + +var indenter = /(?:[({[=:]|[-=]>|\b(?:else|try|with))\s*$/; + +(function() { + + this.toggleCommentLines = function(state, doc, startRow, endRow) { + var i, line; + var outdent = true; + var re = /^\s*\(\*(.*)\*\)/; + + for (i=startRow; i<= endRow; i++) { + if (!re.test(doc.getLine(i))) { + outdent = false; + break; + } + } + + var range = new Range(0, 0, 0, 0); + for (i=startRow; i<= endRow; i++) { + line = doc.getLine(i); + range.start.row = i; + range.end.row = i; + range.end.column = line.length; + + doc.replace(range, outdent ? line.match(re)[1] : "(*" + line + "*)"); + } + }; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + var tokens = this.getTokenizer().getLineTokens(line, state).tokens; + + if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') && + state === 'start' && indenter.test(line)) + indent += tab; + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + this.blockComment = {start: "(*", end: "*)", nestable: true}; + this.$id = "ace/mode/coma"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/src/trywhy3/trywhy3.ml b/src/trywhy3/trywhy3.ml index a1273304d93da310156a328b1acf73710503d9d8..c6ebe3085094e7e2ebbe36e307cf2d56af5d4e13 100644 --- a/src/trywhy3/trywhy3.ml +++ b/src/trywhy3/trywhy3.ml @@ -403,6 +403,7 @@ module FormatList = struct let mode = match lang with | "python" -> !!"python" + | "coma" -> !!"coma" | "micro-C" -> !!"c_cpp" | _ -> !!"why3" in let mode = !!"ace/mode/" ## concat mode in diff --git a/src/trywhy3/why3_worker.ml b/src/trywhy3/why3_worker.ml index 96c7d15b524c48ab539ca23ec5a241a86eda0d34..9ba79a85f2270495a4bb3bd33577e2f19d58e400 100644 --- a/src/trywhy3/why3_worker.ml +++ b/src/trywhy3/why3_worker.ml @@ -79,11 +79,11 @@ module Task = type task_info = { task : task_kind; - parent_id : id; - mutable status : status; - mutable subtasks : id list; - loc : why3_loc list; - expl : string; + parent_id : id; + mutable status : status; + mutable subtasks : id list; + loc : why3_loc list; + expl : string; pretty : string; } @@ -102,7 +102,6 @@ module Task = Some (a,b,c,d) else None - let warnings = ref [] let clear_warnings () = warnings := [] let () = @@ -111,7 +110,6 @@ module Task = let _, a, b,_, _ = Loc.get loc in warnings := ((a-1,b), msg) :: !warnings) - let premise_kind = function | { Term. t_node = Term.Tnot _; t_loc = None } -> "why3-loc-neg-premise" | _ -> "why3-loc-premise" @@ -170,11 +168,11 @@ module Task = in let task_info = { task = Task task; - parent_id = parent_id; - status = StNew; - subtasks = []; - loc = id_loc @ (collect_locs task); - expl = expl; + parent_id = parent_id; + status = StNew; + subtasks = []; + loc = id_loc @ (collect_locs task); + expl = expl; pretty = task_text task; } in @@ -185,8 +183,8 @@ module Task = let th_id = gen_id () in let tasks = Why3Task.split_theory th None None in let task_ids = List.fold_left (fun acc t -> - let tid = register_task th_id t in - tid:: acc) [] tasks in + let tid = register_task th_id t in + tid:: acc) [] tasks in Hashtbl.add task_table th_id { task = Theory th; parent_id = 0; @@ -206,26 +204,26 @@ module Task = let rec loop id st acc = match get_info_opt id with | Some info when info.status <> st -> - info.status <- st; + info.status <- st; let acc = (UpdateStatus (st, id)) :: acc in begin match get_info_opt info.parent_id with None -> acc | Some par_info -> - let has_new, has_unknown = - List.fold_left - (fun (an, au) id -> - let info = Hashtbl.find task_table id in - (an || info.status = StNew), (au || info.status = StUnknown)) - (false, false) par_info.subtasks - in - let par_status = + let has_new, has_unknown = + List.fold_left + (fun (an, au) id -> + let info = Hashtbl.find task_table id in + (an || info.status = StNew), (au || info.status = StUnknown)) + (false, false) par_info.subtasks + in + let par_status = if has_new then StNew else if has_unknown then StUnknown else StValid - in - if par_info.status <> par_status then - loop info.parent_id par_status acc + in + if par_info.status <> par_status then + loop info.parent_id par_status acc else acc end | _ -> acc @@ -266,12 +264,12 @@ let rec why3_prove ?(steps= ~-1) id = let rec why3_split t orig id steps unfold = let open Task in match Trans.apply split_trans orig with - | [] -> () - | [ child ] when Why3.Task.task_equal child orig -> - if unfold then why3_split t (Trans.apply Inlining.goal orig) id steps false - | subtasks -> - t.subtasks <- List.map (fun t -> register_task id t) subtasks; - List.iter (fun i -> why3_prove i ~steps) t.subtasks + | [] -> () + | [ child ] when Why3.Task.task_equal child orig -> + if unfold then why3_split t (Trans.apply Inlining.goal orig) id steps false + | subtasks -> + t.subtasks <- List.map (fun t -> register_task id t) subtasks; + List.iter (fun i -> why3_prove i ~steps) t.subtasks let why3_split steps id = let open Task in @@ -367,14 +365,14 @@ let why3_run f format lang code = | Loc.Located(loc,e') -> let msg = Pp.sprintf "error %a: %a" Loc.pp_position_no_file loc - Exn_printer.exn_printer e' + Exn_printer.exn_printer e' in let _, bl, bc, el, ec = Loc.get loc in W.send (ErrorLoc ((bl-1, bc, el-1, ec),msg)) | e -> W.send (Error (Pp.sprintf - "unexpected exception: %a (%s)" Exn_printer.exn_printer e - (Printexc.to_string e))) + "unexpected exception: %a (%s)" Exn_printer.exn_printer e + (Printexc.to_string e))) let handle_message = function | Transform (Split steps, id) -> why3_split steps id