process_command(system,Codes,Args,Stream,LineNr) -->
!,
{atom_codes(Cmd,Codes),
maplist(codes_to_arg,Args,CmdArgs),
format_stream(Stream,'>>> ~w ~w~n',[Cmd,CmdArgs]),
system_call(Cmd,CmdArgs,Text,ErrorTextAsCodeList,JExit),
format_stream(Stream,'~s~n',[Text]),
(ErrorTextAsCodeList=[] -> true ;
add_latex_processor_error('Error executing command on line: ',LineNr)),
(JExit=exit(0) -> true ;
add_latex_processor_error('Error return code executing command on line: ',LineNr:JExit))}.
process_command(let,Codes,[Expr|Args],Stream,LineNr) --> % \problet calls \probrepl with print option and prints let id = ...
!,
{ atom_codes(ID,Codes),
%(member("ascii",Args) -> set_bvisual2_translation_mode(ascii) ; set_latex_mode,set_bvisual2_translation_mode(latex)),
translate:translate_bexpression(b(identifier(ID),any,[]),IDS),
format_stream(Stream,'let\\ ~w = ',[IDS]),
append(["let ",Codes," = ",Expr],NewCodes)},
process_command(repl,NewCodes,["print"|Args],Stream,LineNr).
process_command(repl,Codes,Args,Stream,LineNr) --> % \probrepl
{ dformat(user_output,"executing ProB REPL command on line ~w: ~s (~w)~n",[LineNr,Codes,Args]),
setup_prefs_for_command(Args,CHNG),
call_cleanup((get_preference(expand_avl_upto,Max),
set_preference(expand_avl_upto,-1), % means no limit
eval_codes_success(LineNr,Codes,exists,StringResult,_EnumWarning,LocalState),
(member("print",Args) ->
eval_strings:last_expression(_,TypedExpr),
print_expr(Stream,TypedExpr,Args)
; true),
(member("silent",Args) -> true
; string_result_false_or_unknown(StringResult) -> write_string_result(Stream,Args,StringResult)
; member("solution",Args) -> write_solution(Stream,Args,LocalState)
; write_string_result(Stream,Args,StringResult))),
reset_prefs_for_command(Args,CHNG)),
set_preference(expand_avl_upto,Max),
((member("check-true",Args), StringResult \== 'TRUE')
-> tools:ajoin(['Result not TRUE on line ',LineNr,': '],Msg),
add_latex_processor_error(Msg,StringResult)
; true),
(member("store",Args),
(LocalState = [] -> add_latex_processor_error('No bindings to store on line: ',LineNr) ; true),
member(bind(ID,IDValue),LocalState),
(kernel_objects:infer_value_type(IDValue,IDType) -> true ; IDType=any),
store_let_value(ID,IDType,IDValue),fail
; true),
print_last_eval_time(Stream,Args)
}.
process_command(requires,Codes,_Args,_Stream,LineNr) --> % \probrequires
!,
{ version:version_str(CurVersion),
split_chars(Codes,".",VCNrs),
maplist(codes_to_number,VCNrs,VNrs),
dformat(user_output,"checking ProB version on line ~w: ~w (against ~w)~n",[LineNr,VNrs,CurVersion]),
version:compare_against_current_version(VNrs,CompareResult),
(CompareResult = current_older
-> add_latex_processor_error('Version of probcli is older than requested: ',CurVersion)
; CompareResult = current_newer -> format(user_output,"~n*** ProB version newer than required on line ~w: ~s (against ~w)~n~n",[LineNr,Codes,CurVersion])
; true)}.
process_command(print,Codes,Args,Stream,LineNr) --> % \probprint
!,
{ dformat(user_output,"pretty-printing ProB expression on line ~w: ~s (~w)~n",[LineNr,Codes,Args]),
setup_prefs_for_command(Args,CHNG),
call_cleanup(((member("pred",Args) ->eval_strings:repl_parse_predicate(Codes,exists,TypedExpr,_)
; member("expr",Args) -> eval_strings:repl_parse_expression(Codes,TypedExpr,_,_)
; member("subst",Args) -> eval_strings:repl_parse_substitution(Codes,TypedExpr)
; eval_strings:repl_parse_expression(Codes,TypedExpr,_,_) -> true
; eval_strings:repl_parse_predicate(Codes,exists,TypedExpr,_)
),
print_expr(Stream,TypedExpr,Args)
),
reset_prefs_for_command(Args,CHNG))
}.
process_command(expr,Codes,Args,Stream,LineNr) -->
!,
{ dformat(user_output,"evaluating ProB expression on line ~w: ~s (~w)~n",[LineNr,Codes,Args]),
setup_prefs_for_command(Args,CHNG),
call_cleanup((get_preference(expand_avl_upto,Max),
set_preference(expand_avl_upto,-1), % means no limit
eval_expression_codes_success(Codes,StringResult,_EnumWarning,_LocalState,Typed),
translate_bexpression(Typed,PS),
%tools:print_bt_message(trans(PS)),
(member("value",Args) -> true % we only print value
; member("silent",Args) -> true % we only print value
; write_stream(Stream,PS), write_stream(Stream,' = ')),
((member("string",Args),eval_strings:get_last_result_value(_,string,string(Value)))
-> write_stream(Stream,Value) % remove string quotes
; write_stream(Stream,StringResult))
),
reset_prefs_for_command(Args,CHNG)),
print_last_eval_time(Stream,Args),
set_preference(expand_avl_upto,Max)}.
process_command(table,Codes,Args,Stream,LineNr) -->
% options for \probtable : no-tabular, no-hline, no-headings, no-row-numbers, max-table-size=NR
!,
{ dformat(user_output,"evaluating ProB expression as table on line ~w: ~s (~w)~n",[LineNr,Codes,Args]),
set_latex_mode,
call_cleanup( (eval_codes_success(LineNr,Codes,exists,_StringResult,_EnumWarning,_LocalState),
eval_strings:get_last_result_value(Expr,_,Value),
maplist(codes_to_arg,Args,Options),
print_value_as_table(Stream,Expr,Value,[latex|Options])),
unset_latex_mode)
}.
process_command(dotcmd,Codes,Args,_Stream,LineNr) --> % probdotcmd: call ProB Dot generation command such as state_space, signature_merge, dfa_merge, state_as_graph, invariant, properties, ...
{atom_codes(Cmd,Codes), process_dot_command(Cmd,Args,LineNr)}.
process_command(dot,Codes,Args,_Stream,LineNr) -->
{ dformat(user_output,"evaluating ProB expression or predicate as dot on line ~w: ~s (~w)~n",[LineNr,Codes,Args]),
atom_codes(Atom,Codes),
(Args = [FileCodes|T]
-> % process Filename in case \probexpr used there; tell used to re-direct any normal print,... away from FCStream
with_open_stream_to_codes(process_line(FCStream,LineNr,FileCodes,[]),
FCStream,NewFileCodes,[]),
atom_codes(File,NewFileCodes), %tcltk_interface:tcltk_show_expression_as_dot(Atom,File),
expand_file_relativ_to_latex_file(File,EFile),
set_eval_dot_file(EFile),
call_cleanup(eval_codes_success(LineNr,Codes,exists,_StringResult,_EnumWarning,_LocalState),
unset_eval_dot_file),
% we could call dotsrc(state_as_dot_graph):print_cstate_graph(_LocalState,File)
(T= [PDF_Codes|RestArgs] ->
% also process PDF_Codes: in case \probexpr used
with_open_stream_to_codes(process_line(FCStream2,LineNr,PDF_Codes,[]),
FCStream2,NewPDF_Codes,[]),
dformat(user_output,' ~s ==> ~s ~n',[PDF_Codes,NewPDF_Codes]),
atom_codes(PDFFile,NewPDF_Codes),
expand_file_relativ_to_latex_file(PDFFile,EPDFFile),
gen_pdf(EFile,RestArgs,EPDFFile)
; true % user will have to generate PDF in Makefile
)
; add_latex_processor_error('No file provided for probdot and expression: ',Atom)
)
}.
process_command(if,TestC,Args,Stream,LineNr) -->
{ dformat(user_output,"evaluating ProB if-construct on line ~w: ~s (~w)~n",[LineNr,TestC,Args]),
Args = [ LatexTRUE, LatexFALSE],
eval_codes_success(LineNr,TestC,exists,StringResult,_EnumWarning,_LocalState), % TO DO: refactor eval_codes to return various number of results in list
dformat(user_output,'Value for probif: ~w~n',[StringResult]),
(StringResult = 'TRUE' -> process_line(Stream,LineNr,LatexTRUE,[])
; StringResult = 'FALSE' -> process_line(Stream,LineNr,LatexFALSE,[])
; StringResult = 'UNKNOWN' -> add_latex_processor_error('UNKNOWN predicate or BOOL expression result for probif: ',LineNr)
; add_latex_processor_error('Not a predicate or BOOL expression for probif: ',LineNr)
)
}.
process_command(for,VARC,Args,Stream,LineNr) -->
{ dformat(user_output,"evaluating ProB for-construct on line ~w: ~s (~w)~n",[LineNr,VARC,Args]),
Args = [ EXPRC, LATEX],
atom_codes(ID,VARC), % the iteration variable
eval_expression_codes_success(EXPRC,_StringResult,_EnumWarning,_LocalState,_Typed),
eval_strings:get_last_result_value(_,Type,Value), %print(value(Value,Type)),nl,
is_set_type(Type,IDType),
custom_explicit_sets:expand_custom_set_to_list(Value,ExpValue,_,probfor),
prob_foreach(ExpValue,ID,IDType,LATEX,Stream,LineNr)
}.