%% generate_preamble % generates the preamble for the eml code, the preamble is % everything before the first if statement, this is seperated % out to make the code simpler. % inputs: % object:EMLGenerator - current object % outputs: % code:string - string of eml code % Author: Colin Eles elesc@mcmaster.ca % Organization: McMaster Centre for Software Certification function code = generate_preamble(object) code = []; function_name = EMLGenerator.parse_inputs(object.data.function_name); %generate input list inputs = ca.mcmaster.cas.tabularexpressiontoolbox.matlab2smt.VariableParser(object.data.function_inputs); parsed_input = inputs.getVarList(); input_iter = parsed_input.iterator() input = []; while input_iter.hasNext() var = input_iter.next() input = [input char(var.name())]; if input_iter.hasNext() input = [input ',']; end end output = []; if (object.data.multi_mode == 1) for i=1:size(object.data.Grid1.cells,2) parsed_output = EMLGenerator.parse_inputs(strtrim(char(object.data.Grid1.cells(i).cond_text))); output = [output char(parsed_output{1}(1))]; if i ~= size(object.data.Grid1.cells,2) output = [output ',']; end end else output = 'output'; end exception_flag = object.data.settings.except; if (exception_flag) code = sprintf('function [%s, exception] = %s(%s)\n%s\n',output,char(function_name{1}(1)),input,'%%#eml'); else code = sprintf('function [%s] = %s(%s)\n%s\n',output,char(function_name{1}(1)),input,'%%#eml'); end % simulink forces you to have an output for all execution paths % since it can't compute completness and disjointness we need % to have a default value, if the user builds the table % properly the default value will never be used. since % different types might have a different default value, the % temporary solution is just to use one of the outputs from our % table, we will use the first cell because it is % guaranteed to % be filled in, regardless of the dimensionality of the table. left_top_right_top_cell = object.data.Grid2.cells(1); while size(left_top_right_top_cell.subgrid) ~= 0 left_top_right_top_cell = left_top_right_top_cell.subgrid.cells(1); end if (object.data.multi_mode == 1) for i=1:size(object.data.Grid1.cells,2) parsed_output = EMLGenerator.parse_inputs(strtrim(char(object.data.Grid1.cells(i).cond_text))); output_str = char(parsed_output{1}(1)); code = [code sprintf('%s=%s;\n',output_str,EMLGenerator.type_convert(output_str,object.datatype,char(object.data.Grid0.search_return(object.data.Grid1.cells(i), left_top_right_top_cell).result_text)))]; end else test = 'output'; output_string = EMLGenerator.type_convert(test,object.datatype,char(object.data.Grid0.Cells(1).result_text) ); code = [code sprintf('output=%s;\n', output_string )]; end if (exception_flag) % generate NaN exceptions nan_string = ''; % genereate constraint exception cons_string = ''; for i = 1:size(parsed_input,2) % for each input consider if a NaN nan_string = [nan_string 'isnan(' char(parsed_input{i}(1)) ')']; if i ~= size(parsed_input,2) nan_string = [nan_string '||']; end if size(parsed_input{i},2) == 2 str = regexp(parsed_input{i}(2),'(?<=\|).*(?=})','match','once'); if (~isempty(char(str))) cons_string = [cons_string sprintf('if ~(%s) \n exception = true;\n return;\nelse\n exception = false;\nend\n',char(str))]; end end end code = [code sprintf('if (%s) \n exception = true;\n return;\nelse\n exception = false;\nend\n',nan_string)]; code = [code cons_string]; end end