2 * Translator from Modelica 2.x to flat Modelica
\r
4 * Copyright (C) 2005 - 2007 Imagine S.A.
\r
5 * For more information or commercial use please contact us at www.amesim.com
\r
7 * This program is free software; you can redistribute it and/or
\r
8 * modify it under the terms of the GNU General Public License
\r
9 * as published by the Free Software Foundation; either version 2
\r
10 * of the License, or (at your option) any later version.
\r
12 * This program is distributed in the hope that it will be useful,
\r
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 * GNU General Public License for more details.
\r
17 * You should have received a copy of the GNU General Public License
\r
18 * along with this program; if not, write to the Free Software
\r
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
23 type ('a, 'b) node =
\r
31 enclosing_instance: instance option;
\r
33 elements: instance_elements Lazy.t
\r
36 and instance_elements =
\r
38 named_elements: (string * element_description) list;
\r
39 unnamed_elements: equation_or_algorithm_clause list
\r
42 and element_description =
\r
45 element_nature: element_nature Lazy.t
\r
48 and element_nature =
\r
49 | Class of class_definition
\r
50 | Component of component_description
\r
52 and class_definition =
\r
54 class_type: Types.class_specifier;
\r
56 class_flow: bool option;
\r
57 class_variability: Types.variability option;
\r
58 class_causality: Types.causality option;
\r
59 description: description;
\r
60 modification: modification_argument list;
\r
61 class_location: Parser.location
\r
64 and path = path_element list
\r
71 | ClassDescription of context * class_description
\r
72 | PredefinedType of predefined_type
\r
74 and class_description =
\r
76 class_kind: Types.kind;
\r
77 class_annotations: (annotation list) Lazy.t;
\r
78 long_description: NameResolve.long_description
\r
82 | InverseFunction of inverse_function Lazy.t
\r
83 | UnknownAnnotation of Parser.location Syntax.class_modification Lazy.t
\r
85 and inverse_function =
\r
87 function_class: class_definition;
\r
88 arguments: (string * string) list
\r
91 and class_modification = (string * modification_argument) list
\r
93 and modification_argument =
\r
96 action: modification_action
\r
99 and modification_action =
\r
100 | ElementModification of modification
\r
101 | ElementRedeclaration of element_description
\r
104 | Modification of class_modification * expression Lazy.t option
\r
105 | Assignment of expression Lazy.t
\r
106 | Equality of expression Lazy.t
\r
108 and component_description =
\r
110 component_path: path;
\r
112 variability: Types.variability;
\r
113 causality: Types.causality;
\r
114 component_nature: component_nature Lazy.t;
\r
115 declaration_equation: expression Lazy.t option;
\r
117 component_location: Parser.location;
\r
121 and component_nature =
\r
122 | DynamicArray of component_description
\r
123 (* one representative member of the collection *)
\r
124 | Instance of instance
\r
125 | PredefinedTypeInstance of predefined_type_instance
\r
126 | StaticArray of component_description array
\r
128 and predefined_type_instance =
\r
130 predefined_type: predefined_type;
\r
131 attributes: (string * expression Lazy.t) list
\r
134 and predefined_type =
\r
141 and equation_or_algorithm_clause =
\r
142 | EquationClause of NameResolve.validity * equation list Lazy.t
\r
143 | AlgorithmClause of NameResolve.validity * algorithm list Lazy.t
\r
145 and validity = Initial | Permanent
\r
147 and equation = (equation_desc list, NameResolve.equation) node
\r
149 and equation_desc =
\r
150 | Equal of expression * expression
\r
151 | ConditionalEquationE of (expression * equation list) list *
\r
153 | ConnectFlows of NameResolve.sign * expression *
\r
154 NameResolve.sign * expression
\r
155 | WhenClauseE of (expression * equation list) list
\r
157 and algorithm = (algorithm_desc list, NameResolve.algorithm) node
\r
159 and algorithm_desc =
\r
160 | Assign of expression * expression
\r
161 | FunctionCallA of expression * expression list
\r
162 | MultipleAssign of expression list * expression * expression list
\r
165 | ConditionalEquationA of (expression * algorithm list) list *
\r
167 | ForClauseA of expression (* range *) * algorithm list
\r
168 | WhileClause of expression * algorithm list
\r
169 | WhenClauseA of (expression * algorithm list) list
\r
172 | BinaryOperation of binary_operator_kind * expression * expression
\r
173 | ClassReference of class_definition
\r
174 | ComponentReference of component_description
\r
175 | EnumerationElement of string
\r
177 | FieldAccess of expression * string
\r
178 | FunctionCall of expression * expression list
\r
179 | If of (expression (* condition *) * expression) list *
\r
180 expression (* default *)
\r
181 | IndexedAccess of expression * expression list (* subscripts *)
\r
183 | LoopVariable of int (* number of nested for loops to skip *)
\r
184 | NoEvent of expression
\r
185 | PredefinedIdentifier of string
\r
186 | Range of expression * expression * expression
\r
188 | Record of (string * expression) list
\r
191 | Tuple of expression list
\r
192 | UnaryOperation of unary_operator_kind * expression
\r
193 | Vector of expression array
\r
194 | VectorReduction of expression list (* ranges *) * expression
\r
196 and unary_operator_kind =
\r
200 and binary_operator_kind =
\r
217 toplevel: (string * element_description) list Lazy.t;
\r
219 context_flow: bool option;
\r
220 context_variability: Types.variability option;
\r
221 context_causality: Types.causality option;
\r
222 parent_context: context option; (* for normal parent scope lookup *)
\r
223 class_context: context_nature; (* for normal (class-based) lookup *)
\r
224 instance_context: instance option; (* for dynamically scoped identifiers *)
\r
225 location: Parser.location;
\r
226 instance_nature: instance_nature
\r
229 and context_nature =
\r
231 | InstanceContext of instance
\r
232 | ForContext of context *
\r
233 expression option (* current value of the loop variable, if available *)
\r
234 | FunctionEvaluationContext of context * expression * expression list
\r
236 (* Error description *)
\r
237 and error_description =
\r
239 err_msg: string list;
\r
240 err_info: (string * string) list;
\r
244 and instance_nature =
\r
246 | ComponentElement of string
\r
248 exception InstantError of error_description
\r
255 let spaces () = for i = 1 to !levels do Printf.printf " " done
\r
258 spaces (); Printf.printf "ForContext %ld\n" i;
\r
262 spaces (); Printf.printf "ReductionContext %ld\n" i;
\r
267 spaces (); Printf.printf "Leaving ForContext\n"
\r
269 let evaluate x = Lazy.force x
\r
274 let l = Array.length a
\r
275 and l' = Array.length a' in
\r
276 if l <> l' then invalid_arg "ArrayExt.map2"
\r
278 let create_array i = f a.(i) a'.(i) in
\r
279 Array.init l create_array
\r
281 let for_all2 f a a' =
\r
282 let l = Array.length a
\r
283 and l' = Array.length a' in
\r
284 if l <> l' then invalid_arg "ArrayExt.for_all2"
\r
286 let rec for_all2' i =
\r
287 i = l || (f a.(i) a'.(i) && for_all2' (i + 1)) in
\r
290 let exists2 f a a' =
\r
291 let l = Array.length a
\r
292 and l' = Array.length a' in
\r
293 if l <> l' then invalid_arg "ArrayExt.exists2"
\r
295 let rec exists2' i =
\r
296 i < l && (f a.(i) a'.(i) || exists2' (i + 1)) in
\r
302 (* Instantiation functions *)
\r
304 let rec evaluate_toplevel_definitions dic defs =
\r
307 toplevel = lazy (dic @ evaluate defs');
\r
309 context_flow = None;
\r
310 context_variability = None;
\r
311 context_causality = None;
\r
312 parent_context = None;
\r
313 class_context = ToplevelContext;
\r
314 instance_context = None;
\r
315 location = {Parser.start = 0; Parser.enddd = 0; filename = Parser.CommandLine};
\r
316 instance_nature = ClassElement
\r
318 and defs' = lazy (List.map (evaluate_toplevel_definition ctx) defs) in
\r
321 and evaluate_toplevel_definition ctx (id, elt_desc) =
\r
322 let elt_loc = [Name id] in
\r
323 let ctx = {ctx with
\r
325 location = elt_desc.NameResolve.element_location;
\r
326 instance_nature = instance_nature_of_element elt_desc} in
\r
327 let elt_nat = elt_desc.NameResolve.element_nature in
\r
331 element_nature = lazy (evaluate_toplevel_element ctx elt_loc elt_nat)
\r
335 and evaluate_toplevel_element ctx elt_loc = function
\r
336 | NameResolve.Component cpnt_desc ->
\r
338 instantiate_component_description ctx [] None elt_loc cpnt_desc in
\r
339 Component cpnt_desc'
\r
340 | NameResolve.Class cl_def ->
\r
341 let cl_def' = evaluate_class_definition ctx [] elt_loc cl_def in
\r
343 | NameResolve.ComponentType _ ->
\r
344 raise (InstantError
\r
345 { err_msg = ["_NotYetImplemented"; "_ComponentTypeElemInstant"];
\r
347 err_ctx = ctx }) (*error*)
\r
348 | NameResolve.PredefinedType _ ->
\r
349 raise (InstantError
\r
350 { err_msg = ["_NotYetImplemented"; "_PredefinedTypeElemInstant"];
\r
352 err_ctx = ctx }) (*error*)
\r
354 and instantiate_class_description ctx modifs rhs elt_loc cl_desc =
\r
355 let elements inst =
\r
358 toplevel = lazy (evaluate ctx.toplevel);
\r
360 parent_context = Some ctx;
\r
361 class_context = InstanceContext inst;
\r
362 instance_context = None
\r
364 instantiate_class_elements ctx' modifs rhs cl_desc.long_description in
\r
367 enclosing_instance = enclosing_instance ctx;
\r
368 kind = cl_desc.class_kind;
\r
369 elements = lazy (elements inst)
\r
373 and enclosing_instance ctx = match ctx.class_context with
\r
374 | ToplevelContext -> None
\r
375 | InstanceContext inst -> Some inst
\r
376 | ForContext (ctx', _) | FunctionEvaluationContext (ctx', _, _) ->
\r
377 enclosing_instance ctx'
\r
379 and instantiate_class_elements ctx modifs rhs long_desc =
\r
380 let rec merge_elements named_elts unnamed_elts = function
\r
383 named_elements = named_elts;
\r
384 unnamed_elements = unnamed_elts
\r
386 | inherited_elts :: inherited_eltss ->
\r
387 let named_elts' = named_elts @ inherited_elts.named_elements
\r
388 and unnamed_elts' = unnamed_elts @ inherited_elts.unnamed_elements in
\r
389 merge_elements named_elts' unnamed_elts' inherited_eltss in
\r
390 let named_elts = long_desc.NameResolve.named_elements
\r
391 and unnamed_elts = long_desc.NameResolve.unnamed_elements
\r
392 and exts = long_desc.NameResolve.extensions in
\r
393 let named_elts' = instantiate_local_named_elements ctx modifs rhs named_elts
\r
394 and unnamed_elts' = instantiate_local_unnamed_elements ctx unnamed_elts
\r
395 and inherited_eltss = instantiate_inherited_elements ctx modifs rhs exts in
\r
396 merge_elements named_elts' unnamed_elts' inherited_eltss
\r
398 and instantiate_local_named_elements ctx modifs rhs named_elts =
\r
399 List.fold_right (instantiate_local_named_element ctx modifs rhs) named_elts []
\r
401 and instantiate_local_named_element ctx modifs rhs (id, elt_desc) named_elts =
\r
402 let rec filter_current_element_modifications = function
\r
404 | (id', arg) :: modifs when id' = id ->
\r
405 arg :: filter_current_element_modifications modifs
\r
406 | _ :: modifs -> filter_current_element_modifications modifs
\r
407 and select_current_element_value = function
\r
409 | Some expr -> Some (lazy (field_access ctx (evaluate expr) id)) in
\r
410 let modifs' = filter_current_element_modifications modifs
\r
411 and rhs' = select_current_element_value rhs
\r
412 and elt_loc = ctx.path @ [Name id] in
\r
413 let ctx = {ctx with
\r
415 location = elt_desc.NameResolve.element_location;
\r
416 instance_nature = instance_nature_of_element elt_desc} in
\r
418 lazy (instantiate_local_element_nature ctx modifs' rhs' elt_loc elt_desc) in
\r
422 redeclare = elt_desc.NameResolve.redeclare;
\r
423 element_nature = elt_nat
\r
425 named_elt :: named_elts
\r
427 and instantiate_local_element_nature ctx modifs rhs elt_loc elt_desc =
\r
428 match elt_desc.NameResolve.element_nature with
\r
429 | NameResolve.Component cpnt_desc ->
\r
431 instantiate_component_description ctx modifs rhs elt_loc cpnt_desc in
\r
432 Component cpnt_desc'
\r
433 | NameResolve.Class cl_def ->
\r
434 let cl_def' = evaluate_class_definition ctx modifs elt_loc cl_def in
\r
436 | NameResolve.ComponentType _ ->
\r
437 raise (InstantError
\r
438 { err_msg = ["_NotYetImplemented"; "_ComponentTypeElemInstant"];
\r
441 | NameResolve.PredefinedType _ ->
\r
442 raise (InstantError
\r
443 { err_msg = ["_NotYetImplemented"; "_PredefinedTypeElemInstant"];
\r
447 and instantiate_component_description ctx modifs rhs elt_loc cpnt_desc =
\r
448 let cpnt_type = evaluate cpnt_desc.NameResolve.component_type in
\r
449 let flow = evaluate cpnt_type.Types.flow
\r
450 and var = evaluate cpnt_type.Types.variability
\r
451 and inout = evaluate cpnt_type.Types.causality
\r
452 and type_spec = evaluate cpnt_desc.NameResolve.type_specifier
\r
453 and dims = evaluate cpnt_desc.NameResolve.dimensions
\r
454 and modifs' = match evaluate cpnt_desc.NameResolve.modification with
\r
457 let modif' = evaluate_modification ctx modif in
\r
458 modifs @ [{ each = false; action = ElementModification modif' }]
\r
459 and cmt = cpnt_desc.NameResolve.comment in
\r
460 component_nature ctx modifs' rhs elt_loc flow var inout type_spec dims cmt
\r
462 and component_nature ctx modifs rhs elt_loc flow var inout type_spec dims cmt =
\r
463 let type_spec' = evaluate_expression ctx type_spec in
\r
464 let ctx = {ctx with location = expression_location ctx type_spec} in
\r
465 expand_array ctx modifs rhs elt_loc flow var inout type_spec' dims cmt
\r
467 and expand_array ctx modifs rhs elt_loc flow var inout type_spec dims cmt =
\r
468 let rec expand_along_dimension dim dims = match dim with
\r
469 | NameResolve.Colon -> expand_dynamic_array dims
\r
470 | NameResolve.Expression expr ->
\r
471 let expr' = evaluate_expression ctx expr in
\r
472 expand_static_array dims expr' expr
\r
473 and expand_dynamic_array dims =
\r
474 (* No need to select modifications since all of them have 'each' set *)
\r
475 let elt_loc' = elt_loc @ [Index 0] in
\r
476 let ctx = { ctx with path = elt_loc' } in
\r
478 expand_array ctx modifs rhs elt_loc' flow var inout type_spec dims cmt in
\r
480 and expand_static_array dims expr' expr =
\r
481 let ctx = {ctx with location = expression_location ctx expr} in
\r
482 let expand_element i =
\r
483 let rec select_subargument arg = match arg.each with
\r
485 | false -> { arg with action = select_subarray arg.action }
\r
486 and select_subarray arg = match arg with
\r
487 | ElementModification modif ->
\r
488 ElementModification (select_submodification modif)
\r
489 | ElementRedeclaration _ -> arg
\r
490 and select_sub_class_modification_element (id, arg) =
\r
491 id, select_subargument arg
\r
492 and select_submodification = function
\r
493 | Modification (modifs, rhs) ->
\r
494 let modifs' = List.map select_sub_class_modification_element modifs
\r
495 and rhs' = select_rhs_subarray rhs in
\r
496 Modification (modifs', rhs')
\r
497 | Assignment expr ->
\r
498 let expr' = lazy (select_row i (evaluate expr)) in
\r
501 let expr' = lazy (select_row i (evaluate expr)) in
\r
503 and select_rhs_subarray = function
\r
505 | Some expr -> Some (lazy (select_row i (evaluate expr)))
\r
506 and select_row i = function
\r
512 | _ -> raise (InstantError
\r
513 { err_msg = ["_IndexOutOfBound"];
\r
515 err_ctx = ctx}) (*error*)
\r
518 let subs = [Integer (Int32.succ (Int32.of_int i))] in
\r
519 evaluate_indexed_access ctx expr subs in
\r
520 let modifs = List.map select_subargument modifs
\r
521 and rhs = select_rhs_subarray rhs
\r
522 and elt_loc = elt_loc @ [Index i] in
\r
523 expand_array ctx modifs rhs elt_loc flow var inout type_spec dims cmt in
\r
526 let a = Array.init (Int32.to_int i) expand_element in
\r
529 raise (InstantError
\r
530 { err_msg = ["_NonIntegerArrayDim"];
\r
532 err_ctx = ctx }) (*error*) in
\r
535 let cl_def = class_definition_of_type_specification ctx type_spec in
\r
536 create_instance ctx modifs rhs elt_loc flow var inout cl_def cmt
\r
539 component_path = elt_loc;
\r
543 component_nature = lazy (expand_along_dimension dim dims);
\r
544 declaration_equation = rhs;
\r
546 component_location = ctx.location;
\r
547 class_name = instance_class_name ctx.instance_nature
\r
550 and create_instance ctx modifs rhs elt_loc flow var inout cl_def cmt =
\r
551 let merge_class_modifications arg modifs = match arg.action with
\r
552 | ElementModification (Modification (modifs', _)) -> modifs' @ modifs
\r
553 | ElementModification (Assignment _ | Equality _) -> modifs
\r
554 | ElementRedeclaration _ -> modifs in
\r
555 let rec declaration_equation modifs rhs =
\r
556 let rec declaration_equation' = function
\r
560 ElementModification (
\r
561 Modification (_, Some expr) | Assignment expr | Equality expr)
\r
562 } :: _ -> Some expr
\r
563 | _ :: args -> declaration_equation' args in
\r
565 | None -> declaration_equation' modifs
\r
567 let flow' = match cl_def.class_flow, ctx.context_flow with
\r
568 | None, None -> flow
\r
569 | Some flow', None | None, Some flow' -> flow || flow'
\r
570 | Some flow', Some flow'' -> flow || flow' || flow''
\r
571 and var' = match cl_def.class_variability, ctx.context_variability with
\r
572 | None, None -> var
\r
573 | Some var', None | None, Some var' -> Types.min_variability var var'
\r
574 | Some var', Some var'' ->
\r
575 Types.min_variability var (Types.min_variability var' var'')
\r
576 and inout' = match inout, cl_def.class_causality with
\r
577 | Types.Input, _ | _, Some Types.Input -> Types.Input
\r
578 | Types.Output, _ | _, Some Types.Output -> Types.Output
\r
579 | _ -> Types.Acausal in
\r
582 merge_class_modifications
\r
583 (modifs @ cl_def.modification)
\r
585 and rhs' = declaration_equation modifs rhs in
\r
586 match cl_def.description with
\r
587 | ClassDescription (ctx', cl_desc) ->
\r
588 let class_name = instance_class_name ctx.instance_nature in
\r
591 context_flow = Some flow';
\r
592 context_variability = Some var';
\r
593 context_causality = Some inout';
\r
594 instance_context = enclosing_instance ctx;
\r
595 instance_nature = ComponentElement class_name
\r
598 component_path = elt_loc;
\r
600 variability = var';
\r
601 causality = inout';
\r
603 lazy (create_class_instance ctx' modifs' rhs' elt_loc cl_desc);
\r
604 declaration_equation = rhs';
\r
606 component_location = ctx'.location;
\r
607 class_name = class_name
\r
609 | PredefinedType predef ->
\r
610 let class_name = instance_class_name ctx.instance_nature in
\r
613 context_flow = Some flow';
\r
614 context_variability = Some var';
\r
615 context_causality = Some inout';
\r
616 instance_nature = ComponentElement class_name
\r
619 component_path = elt_loc;
\r
621 variability = var';
\r
622 causality = inout';
\r
624 lazy (create_predefined_type_instance ctx' modifs' predef);
\r
625 declaration_equation = rhs';
\r
627 component_location = ctx'.location;
\r
628 class_name = class_name
\r
631 and create_temporary_instance ctx cl_def =
\r
632 match cl_def.description with
\r
633 | ClassDescription (ctx', cl_desc) ->
\r
635 component_path = [];
\r
637 variability = Types.Continuous;
\r
638 causality = Types.Acausal;
\r
640 lazy (create_class_instance ctx' [] None [] cl_desc);
\r
641 declaration_equation = None;
\r
643 component_location = ctx'.location;
\r
644 class_name = instance_class_name ctx.instance_nature
\r
646 | PredefinedType predef -> assert false (*error*)
\r
648 and class_definition_of_type_specification ctx type_spec =
\r
649 let predefined_class_specifier = function
\r
650 | "Boolean" -> Types.boolean_class_type
\r
651 | "Integer" -> Types.integer_class_type
\r
652 | "Real" -> Types.real_class_type
\r
653 | "String" -> Types.string_class_type
\r
655 raise (InstantError
\r
656 { err_msg = ["_UnknownIdentifier"; s];
\r
658 err_ctx = ctx }) (*error*)
\r
659 and predefined_class_description = function
\r
660 | "Boolean" -> PredefinedType BooleanType
\r
661 | "Integer" -> PredefinedType IntegerType
\r
662 | "Real" -> PredefinedType RealType
\r
663 | "String" -> PredefinedType StringType
\r
665 raise (InstantError
\r
666 { err_msg = ["_UnknownIdentifier"; s];
\r
668 err_ctx = ctx }) (*error*) in
\r
669 match type_spec with
\r
670 | ClassReference cl_def -> cl_def
\r
671 | PredefinedIdentifier id ->
\r
673 class_type = predefined_class_specifier id;
\r
674 class_path = [Name id];
\r
676 class_variability = None;
\r
677 class_causality = None;
\r
678 description = predefined_class_description id;
\r
680 class_location = ctx.location
\r
682 | _ -> assert false (*error*)
\r
684 and create_class_instance ctx modifs rhs elt_loc cl_desc =
\r
685 let inst = instantiate_class_description ctx modifs rhs elt_loc cl_desc in
\r
688 and create_predefined_type_instance ctx modifs predef =
\r
691 predefined_type = predef;
\r
692 attributes = predefined_type_attributes ctx modifs
\r
694 PredefinedTypeInstance inst
\r
696 and predefined_type_attributes ctx modifs =
\r
697 let rec predefined_type_attributes attrs = function
\r
699 | (id, { action = ElementModification (Equality expr) }) :: modifs
\r
700 when not (List.mem_assoc id attrs) ->
\r
701 let attrs' = (id, expr) :: attrs in
\r
702 predefined_type_attributes attrs' modifs
\r
703 | _ :: modifs -> predefined_type_attributes attrs modifs in
\r
704 predefined_type_attributes [] modifs
\r
706 and instantiate_inherited_elements ctx modifs rhs exts =
\r
707 List.fold_right (instantiate_inherited_element ctx modifs rhs) exts []
\r
709 and instantiate_inherited_element ctx modifs rhs (_, modif_cl) inherited_elts =
\r
710 let instantiate_inherited_element' modifs cl_def =
\r
711 match cl_def.description with
\r
712 | ClassDescription (ctx', cl_desc) ->
\r
713 let ctx' = { ctx with parent_context = Some ctx' } in
\r
714 let long_desc = cl_desc.long_description in
\r
715 instantiate_class_elements ctx' modifs rhs long_desc
\r
716 | PredefinedType _ -> assert false (*error*) in
\r
717 let type_spec = evaluate modif_cl.NameResolve.base_class
\r
718 and modifs' = evaluate modif_cl.NameResolve.class_modification in
\r
719 let type_spec' = evaluate_expression ctx type_spec
\r
720 and ctx = {ctx with location = expression_location ctx type_spec} in
\r
721 let modifs = modifs @ evaluate_class_modification ctx modifs' in
\r
722 match type_spec' with
\r
723 | ClassReference cl_def ->
\r
724 instantiate_inherited_element' modifs cl_def :: inherited_elts
\r
725 | _ -> assert false (*error*)
\r
727 and evaluate_class_definition ctx modifs elt_loc cl_def =
\r
728 match evaluate cl_def.NameResolve.description with
\r
729 | NameResolve.LongDescription long_desc ->
\r
730 let cl_anns = long_desc.NameResolve.class_annotations in
\r
733 class_kind = Types.Class;
\r
734 class_annotations = lazy (evaluate_class_annotations ctx cl_anns);
\r
735 long_description = long_desc
\r
738 class_type = evaluate cl_def.NameResolve.class_type;
\r
739 class_path = elt_loc;
\r
741 class_variability = None;
\r
742 class_causality = None;
\r
743 description = ClassDescription (ctx, cl_def');
\r
744 modification = modifs;
\r
745 class_location = ctx.location
\r
747 | NameResolve.ShortDescription short_desc ->
\r
748 raise (InstantError
\r
749 {err_msg = ["_NotYetImplemented"; "_ShortClassDef"];
\r
751 err_ctx = {ctx with path = elt_loc;
\r
752 instance_nature = ClassElement}})
\r
754 and evaluate_class_annotations ctx cl_anns =
\r
755 let evaluate_inverse_function inv_func =
\r
756 let inv_func = evaluate inv_func in
\r
758 evaluate_expression ctx inv_func.NameResolve.function_class in
\r
760 | ClassReference cl_def ->
\r
762 function_class = cl_def;
\r
763 arguments = inv_func.NameResolve.arguments
\r
765 | _ -> assert false (*error*) in
\r
766 let evaluate_class_annotation cl_ann = match cl_ann with
\r
767 | NameResolve.InverseFunction inv_func ->
\r
768 InverseFunction (lazy (evaluate_inverse_function inv_func))
\r
769 | NameResolve.UnknownAnnotation cl_ann ->
\r
770 UnknownAnnotation cl_ann in
\r
771 List.map evaluate_class_annotation (evaluate cl_anns)
\r
773 and evaluate_class_modification ctx cl_modif =
\r
774 let add_modification_argument arg cl_modif' =
\r
775 match arg.NameResolve.action with
\r
776 | None -> cl_modif'
\r
779 arg.NameResolve.target,
\r
781 each = arg.NameResolve.each;
\r
782 action = evaluate_modification_action ctx modif
\r
784 arg' :: cl_modif' in
\r
785 List.fold_right add_modification_argument cl_modif []
\r
787 and evaluate_modification_action ctx = function
\r
788 | NameResolve.ElementModification modif ->
\r
789 let modif' = evaluate_modification ctx modif in
\r
790 ElementModification modif'
\r
791 | NameResolve.ElementRedeclaration elt_desc ->
\r
792 raise (InstantError
\r
793 { err_msg = ["_NotYetImplemented"; "_ElementRedeclaration"];
\r
797 and evaluate_modification ctx = function
\r
798 | NameResolve.Modification (modifs, rhs) ->
\r
799 let modifs' = evaluate_class_modification ctx modifs
\r
800 and rhs' = evaluate_modification_expression ctx rhs in
\r
801 Modification (modifs', rhs')
\r
802 | NameResolve.Assignment expr ->
\r
803 let expr = evaluate expr in
\r
804 let ctx = {ctx with location = expression_location ctx expr} in
\r
805 raise (InstantError
\r
806 { err_msg = ["_NotYetImplemented"; "_AssignExprInElemModif"];
\r
809 | NameResolve.Equality expr ->
\r
810 let expr' = lazy (evaluate_expression ctx (evaluate expr)) in
\r
813 and evaluate_modification_expression ctx = function
\r
816 let expr' = lazy (evaluate_expression ctx (evaluate expr)) in
\r
819 and instantiate_local_unnamed_elements ctx unnamed_elts =
\r
820 List.map (instantiate_local_unnamed_element ctx) (evaluate unnamed_elts)
\r
822 and instantiate_local_unnamed_element ctx unnamed_elt =
\r
823 match unnamed_elt with
\r
824 | NameResolve.EquationClause (validity, equs) ->
\r
825 EquationClause (validity, lazy (instantiate_equations ctx equs))
\r
826 | NameResolve.AlgorithmClause (validity, algs) ->
\r
827 raise (InstantError
\r
828 { err_msg = ["_NotYetImplemented"; "_AlgoClause"];
\r
832 and instantiate_equations ctx equs =
\r
833 let instantiate_equations' equ equs =
\r
834 let equs' = instantiate_equation ctx equ in
\r
835 { nature = equs'; info = equ } :: equs in
\r
836 List.fold_right instantiate_equations' equs []
\r
838 and instantiate_equation ctx equ = match equ.NameResolve.nature with
\r
839 | NameResolve.Equal (expr, expr') -> instantiate_equal ctx expr expr'
\r
840 | NameResolve.ConditionalEquationE (alts, default) ->
\r
841 instantiate_conditional_equation ctx alts default
\r
842 | NameResolve.ForClauseE (ranges, equs) ->
\r
843 instantiate_for_clause_e ctx ranges equs
\r
844 | NameResolve.ConnectFlows (sign, expr, sign', expr') ->
\r
845 instantiate_connection ctx sign expr sign' expr'
\r
846 | NameResolve.WhenClauseE alts ->
\r
847 instantiate_when_clause_e ctx alts
\r
849 and instantiate_equal ctx expr expr' =
\r
850 let rec equal_expr expr expr' =
\r
851 match expr, expr' with
\r
852 | BinaryOperation (bin_oper_kind, expr1, expr2),
\r
853 BinaryOperation (bin_oper_kind', expr1', expr2') ->
\r
854 (bin_oper_kind = bin_oper_kind') &&
\r
855 (equal_expr expr1 expr1') &&
\r
856 (equal_expr expr2 expr2')
\r
857 | ClassReference cl_def, ClassReference cl_def' ->
\r
858 cl_def.class_path = cl_def'.class_path
\r
859 | ComponentReference cpnt_desc, ComponentReference cpnt_desc' ->
\r
860 cpnt_desc.component_path = cpnt_desc'.component_path
\r
861 | EnumerationElement s, EnumerationElement s' -> s = s'
\r
862 | False, False -> true
\r
863 | FieldAccess (expr, s), FieldAccess (expr', s') ->
\r
864 (equal_expr expr expr') && (s = s')
\r
865 | FunctionCall (expr, exprs), FunctionCall (expr', exprs') ->
\r
866 (equal_expr expr expr') &&
\r
867 (List.length exprs = List.length exprs') &&
\r
868 (List.for_all2 (=) exprs exprs')
\r
869 | If (alts, default), If (alts', default') ->
\r
870 let f (cond, expr) (cond', expr') =
\r
871 (equal_expr cond cond') && (equal_expr expr expr') in
\r
872 (List.length alts = List.length alts') &&
\r
873 (List.for_all2 f alts alts') &&
\r
874 (equal_expr default default')
\r
875 | IndexedAccess (expr, exprs), IndexedAccess (expr', exprs') ->
\r
876 (equal_expr expr expr') &&
\r
877 (List.length exprs = List.length exprs') &&
\r
878 (List.for_all2 (=) exprs exprs')
\r
879 | Integer i, Integer i' -> Int32.compare i i' = 0
\r
880 | LoopVariable i, LoopVariable i' -> i = i'
\r
881 | NoEvent expr, NoEvent expr' -> equal_expr expr expr'
\r
882 | PredefinedIdentifier s, PredefinedIdentifier s' -> s = s'
\r
883 | Range (start, step, stop), Range (start', step', stop') ->
\r
884 (equal_expr start start') &&
\r
885 (equal_expr step step') &&
\r
886 (equal_expr stop stop')
\r
887 | Real f, Real f' -> f = f'
\r
888 | Record elts, Record elts' ->
\r
889 let f (s, expr) (s', expr') =
\r
890 (s = s') && (equal_expr expr expr') in
\r
891 (List.length elts = List.length elts') &&
\r
892 (List.for_all2 f elts elts')
\r
893 | String s, String s' -> s = s'
\r
894 | True, True -> true
\r
895 | Tuple exprs, Tuple exprs' ->
\r
896 (List.length exprs = List.length exprs') &&
\r
897 (List.for_all2 equal_expr exprs exprs')
\r
898 | UnaryOperation (un_oper_kind, expr),
\r
899 UnaryOperation (un_oper_kind', expr') ->
\r
900 (un_oper_kind = un_oper_kind') &&
\r
901 (equal_expr expr expr')
\r
902 | Vector exprs, Vector exprs' ->
\r
903 (Array.length exprs = Array.length exprs') &&
\r
904 (ArrayExt.for_all2 equal_expr exprs exprs')
\r
905 | VectorReduction (exprs, expr), VectorReduction (exprs', expr') ->
\r
906 (List.length exprs = List.length exprs') &&
\r
907 (List.for_all2 equal_expr exprs exprs') &&
\r
908 (equal_expr expr expr')
\r
910 let expr = evaluate_expression ctx expr
\r
911 and expr' = evaluate_expression ctx expr' in
\r
912 match equal_expr expr expr' with
\r
914 | false -> [ Equal (expr, expr') ]
\r
916 and instantiate_conditional_equation ctx alts default =
\r
917 let rec instantiate_alternatives acc = function
\r
918 | [] -> instantiate_default acc default
\r
919 | (cond, equs) :: alts -> instantiate_alternative acc cond equs alts
\r
920 and instantiate_alternative acc cond equs alts =
\r
921 let cond' = evaluate_expression ctx cond in
\r
923 | False -> instantiate_alternatives acc alts
\r
924 | True -> instantiate_default acc equs
\r
926 let equs' = instantiate_equations ctx equs in
\r
927 instantiate_alternatives ((cond', equs') :: acc) alts
\r
928 and instantiate_default acc equs =
\r
929 let equs' = instantiate_equations ctx equs in
\r
930 [ConditionalEquationE (List.rev acc, equs')] in
\r
931 let alts' = instantiate_alternatives [] alts in
\r
932 List.flatten (List.map (expand_equation ctx) alts')
\r
934 and expand_equation ctx equ =
\r
935 let rec expand_equation' equ =
\r
936 let expand_conditional_equation alts default =
\r
937 let add_alternative (b, equs) altss =
\r
938 let g equ = List.flatten (List.map expand_equation' equ.nature) in
\r
939 let equs' = List.flatten (List.map g equs) in
\r
940 let f (expr1, expr2) (expr1', expr2') = match expr1, expr2 with
\r
941 | If (alts1, default1), If (alts2, default2) ->
\r
942 If ((b, expr1') :: alts1, default1),
\r
943 If ((b, expr2') :: alts2, default2)
\r
944 | _ -> assert false in
\r
946 List.map2 f altss equs'
\r
949 raise (InstantError
\r
950 {err_msg = ["_InvalidCondEquation"];
\r
953 let g equ = List.flatten (List.map expand_equation' equ.nature) in
\r
954 let default' = List.flatten (List.map g default) in
\r
955 let f = function (expr1, expr2) -> If ([], expr1), If ([], expr2) in
\r
956 List.fold_right add_alternative alts (List.map f default') in
\r
958 | ConditionalEquationE (alts, default) ->
\r
959 expand_conditional_equation alts default
\r
960 | Equal (expr, expr') -> [ expr, expr' ]
\r
962 raise (InstantError
\r
963 {err_msg = ["_InvalidCondEquation"];
\r
966 let f (expr, expr') = Equal (expr, expr') in
\r
967 List.map f (expand_equation' equ)
\r
969 and instantiate_when_clause_e ctx alts =
\r
970 let instantiate_alternative (cond, equs) =
\r
971 let cond' = evaluate_expression ctx cond in
\r
972 let equs' = instantiate_equations ctx equs in
\r
974 [WhenClauseE (List.map instantiate_alternative alts)]
\r
976 and instantiate_connection ctx sign expr sign' expr' =
\r
977 let expr = evaluate_expression ctx expr
\r
978 and expr' = evaluate_expression ctx expr' in
\r
979 [ConnectFlows (sign, expr, sign', expr')]
\r
981 and instantiate_for_clause_e ctx ranges equs =
\r
982 let rec instantiate_for_clause_e' ctx = function
\r
983 | [] -> List.flatten (List.map (instantiate_equation ctx) equs)
\r
984 | ranges -> equations_of_reduction ctx ranges
\r
985 and equations_of_reduction ctx ranges = match ranges with
\r
986 | (Vector exprs) :: ranges ->
\r
990 class_context = ForContext (ctx, Some expr)
\r
992 instantiate_for_clause_e' ctx' ranges in
\r
993 List.flatten (List.map f (Array.to_list exprs))
\r
995 raise (InstantError
\r
996 {err_msg = ["_InvalidForClauseRange"];
\r
999 let ranges = List.map (evaluate_expression ctx) ranges in
\r
1000 instantiate_for_clause_e' ctx ranges
\r
1002 and evaluate_expression ctx expr =
\r
1003 let ctx = {ctx with location = expression_location ctx expr} in
\r
1004 match expr.NameResolve.nature with
\r
1005 | NameResolve.BinaryOperation (binop, expr, expr') ->
\r
1006 evaluate_binary_operation ctx binop expr expr'
\r
1007 | NameResolve.DynamicIdentifier (level, id) ->
\r
1008 evaluate_dynamic_identifier ctx level id
\r
1009 | NameResolve.False -> False
\r
1010 | NameResolve.FieldAccess (expr, id) ->
\r
1011 evaluate_field_access ctx expr id
\r
1012 | NameResolve.FunctionArgument pos -> evaluate_function_argument ctx pos
\r
1013 | NameResolve.FunctionCall (expr, exprs, expr') ->
\r
1014 evaluate_function_call ctx expr exprs expr'
\r
1015 | NameResolve.FunctionInvocation exprs ->
\r
1016 evaluate_function_invocation ctx exprs
\r
1017 | NameResolve.If (alts, default) -> evaluate_if ctx alts default
\r
1018 | NameResolve.IndexedAccess (expr, exprs) ->
\r
1019 let expr = evaluate_expression ctx expr
\r
1020 and exprs = List.map (evaluate_expression ctx) exprs in
\r
1021 evaluate_indexed_access ctx expr exprs
\r
1022 | NameResolve.Integer i -> Integer i
\r
1023 | NameResolve.LocalIdentifier (level, id) ->
\r
1024 evaluate_local_identifier ctx level id
\r
1025 | NameResolve.LoopVariable level -> evaluate_loop_variable ctx level
\r
1026 | NameResolve.NoEvent expr -> evaluate_no_event ctx expr
\r
1027 | NameResolve.PredefinedIdentifier id -> PredefinedIdentifier id
\r
1028 | NameResolve.Range (start, step, stop) ->
\r
1029 evaluate_range ctx start step stop
\r
1030 | NameResolve.Real f -> Real f
\r
1031 | NameResolve.String s -> String s
\r
1032 | NameResolve.ToplevelIdentifier id ->
\r
1033 evaluate_toplevel_identifier ctx id
\r
1034 | NameResolve.True -> True
\r
1035 | NameResolve.Tuple exprs -> evaluate_tuple ctx exprs
\r
1036 | NameResolve.UnaryOperation (unop, expr) ->
\r
1037 evaluate_unary_operation ctx unop expr
\r
1038 | NameResolve.VectorReduction (ranges, expr) ->
\r
1039 evaluate_vector_reduction ctx ranges expr
\r
1040 | NameResolve.Vector exprs -> evaluate_vector ctx exprs
\r
1041 | NameResolve.Coercion (coer, expr) ->
\r
1042 evaluate_coercion ctx coer expr
\r
1044 and evaluate_binary_operation ctx binop expr expr' =
\r
1045 let expr = evaluate_expression ctx expr
\r
1046 and expr' = evaluate_expression ctx expr' in
\r
1047 let expr = flatten_expression expr
\r
1048 and expr' = flatten_expression expr' in
\r
1050 | NameResolve.And -> evaluate_and expr expr'
\r
1051 | NameResolve.Divide -> evaluate_divide ctx expr expr'
\r
1052 | NameResolve.EqualEqual -> evaluate_equalequal expr expr'
\r
1053 | NameResolve.GreaterEqual -> evaluate_greater_equal expr expr'
\r
1054 | NameResolve.Greater -> evaluate_greater expr expr'
\r
1055 | NameResolve.LessEqual -> evaluate_less_equal expr expr'
\r
1056 | NameResolve.Less -> evaluate_less expr expr'
\r
1057 | NameResolve.Times -> evaluate_times expr expr'
\r
1058 | NameResolve.NotEqual -> evaluate_not_equal expr expr'
\r
1059 | NameResolve.Or -> evaluate_or expr expr'
\r
1060 | NameResolve.Plus -> evaluate_plus expr expr'
\r
1061 | NameResolve.Power -> evaluate_power ctx expr expr'
\r
1062 | NameResolve.Minus -> evaluate_minus expr expr'
\r
1064 and evaluate_dynamic_identifier ctx level id =
\r
1065 let rec evaluate_dynamic_identifier' inst level =
\r
1066 match level, inst.enclosing_instance with
\r
1067 | 0, _ -> instance_field_access ctx inst id
\r
1068 | _, Some inst -> evaluate_dynamic_identifier' inst (level - 1)
\r
1069 | _, None -> assert false (*error*) in
\r
1070 match ctx.instance_context with
\r
1071 | Some inst -> evaluate_dynamic_identifier' inst level
\r
1072 | None -> assert false (*error*)
\r
1074 and evaluate_field_access ctx expr id =
\r
1075 let expr = evaluate_expression ctx expr in
\r
1076 field_access ctx expr id
\r
1078 and evaluate_function_argument ctx pos = match ctx.class_context with
\r
1079 | FunctionEvaluationContext (_, expr, _) when pos = 0 -> expr
\r
1080 | FunctionEvaluationContext (_, _, exprs) -> List.nth exprs (pos - 1)
\r
1081 | ForContext (ctx', _) -> evaluate_function_argument ctx' pos
\r
1082 | InstanceContext _ | ToplevelContext -> assert false (*error*)
\r
1084 and evaluate_function_call ctx expr exprs expr' =
\r
1085 let expr = evaluate_expression ctx expr
\r
1086 and exprs = List.map (evaluate_expression ctx) exprs in
\r
1087 let exprs = List.map flatten_expression exprs in
\r
1090 class_context = FunctionEvaluationContext (ctx, expr, exprs)
\r
1092 evaluate_expression ctx' expr'
\r
1094 and evaluate_function_invocation ctx exprs =
\r
1095 let exprs = List.map (evaluate_expression ctx) exprs in
\r
1096 let exprs = List.map flatten_expression exprs in
\r
1097 let evaluate_function_with_arguments = function
\r
1098 | ClassReference cl_def ->
\r
1099 evaluate_class_function_invocation cl_def exprs
\r
1100 | PredefinedIdentifier s ->
\r
1101 evaluate_predefined_function_invocation ctx s exprs
\r
1102 | ComponentReference _ ->
\r
1103 raise (InstantError
\r
1104 { err_msg = ["_NotYetImplemented"; "_ComponentFuncInvocation"];
\r
1107 | _ -> assert false (*error*) in
\r
1108 let rec evaluate_function_invocation' ctx = match ctx.class_context with
\r
1109 | FunctionEvaluationContext (_, expr, _) ->
\r
1110 evaluate_function_with_arguments expr
\r
1111 | ForContext (ctx', _) -> evaluate_function_invocation' ctx'
\r
1112 | InstanceContext _ | ToplevelContext -> assert false (*error*) in
\r
1113 evaluate_function_invocation' ctx
\r
1115 and evaluate_if ctx alts default =
\r
1116 let create_if alts default = match alts with
\r
1118 | _ :: _ -> If (alts, default) in
\r
1119 let rec evaluate_alternatives alts' alts = match alts with
\r
1121 let default = evaluate_expression ctx default in
\r
1122 create_if (List.rev alts') default
\r
1123 | (expr, expr') :: alts ->
\r
1124 let expr = evaluate_expression ctx expr in
\r
1125 evaluate_alternative expr expr' alts' alts
\r
1126 and evaluate_alternative expr expr' alts' alts = match expr with
\r
1128 let default = evaluate_expression ctx expr' in
\r
1129 create_if (List.rev alts') default
\r
1130 | False -> evaluate_alternatives alts' alts
\r
1132 let expr' = evaluate_expression ctx expr' in
\r
1133 evaluate_alternatives ((expr, expr') :: alts') alts in
\r
1134 evaluate_alternatives [] alts
\r
1136 and evaluate_indexed_access ctx expr exprs =
\r
1137 let rec vector_indexed_access exprs' exprs = match exprs with
\r
1139 | Integer i :: exprs ->
\r
1142 exprs'.(Int32.to_int i - 1)
\r
1144 raise (InstantError
\r
1145 { err_msg = ["_IndexOutOfBound"];
\r
1147 err_ctx = ctx}) (*error*) in
\r
1148 evaluate_indexed_access ctx expr' exprs
\r
1149 | (Vector subs) :: exprs ->
\r
1150 let f sub = vector_indexed_access exprs' (sub :: exprs) in
\r
1151 Vector (Array.map f subs)
\r
1152 | _ -> IndexedAccess (expr, exprs)
\r
1153 and component_indexed_access cpnt_desc exprs =
\r
1154 let rec static_array_indexed_access cpnt_descs exprs = match exprs with
\r
1156 | Integer i :: exprs ->
\r
1157 let i' = Int32.to_int i in
\r
1158 if Array.length cpnt_descs >= i' then
\r
1159 let cpnt_desc = cpnt_descs.(i' - 1) in
\r
1160 let expr' = ComponentReference cpnt_desc in
\r
1161 evaluate_indexed_access ctx expr' exprs
\r
1163 raise (InstantError
\r
1164 { err_msg = ["_IndexOutOfBound"];
\r
1166 err_ctx = ctx}) (*error*)
\r
1167 | (Vector subs) :: exprs ->
\r
1168 let f sub = static_array_indexed_access cpnt_descs (sub :: exprs) in
\r
1169 Vector (Array.map f subs)
\r
1170 | exprs -> IndexedAccess (expr, exprs) in
\r
1171 match evaluate cpnt_desc.component_nature with
\r
1172 | DynamicArray _ -> IndexedAccess (ComponentReference cpnt_desc, exprs)
\r
1173 | StaticArray cpnt_descs ->
\r
1174 static_array_indexed_access cpnt_descs exprs
\r
1175 | Instance _ | PredefinedTypeInstance _ -> expr in
\r
1176 match expr, exprs with
\r
1178 | ComponentReference cpnt_desc, _ ->
\r
1179 component_indexed_access cpnt_desc exprs
\r
1180 | Vector exprs', _ ->
\r
1181 vector_indexed_access exprs' exprs
\r
1182 | If (alts, default), _ ->
\r
1183 let f (cond, expr) = (cond, evaluate_indexed_access ctx expr exprs) in
\r
1184 If (List.map f alts, evaluate_indexed_access ctx default exprs)
\r
1185 | _ -> IndexedAccess (expr, exprs)
\r
1187 and evaluate_local_identifier ctx level id =
\r
1188 let rec evaluate_local_identifier' ctx inst level =
\r
1189 match level, ctx.parent_context with
\r
1190 | 0, _ -> instance_field_access ctx inst id
\r
1191 | _, Some ctx -> evaluate_local_identifier ctx (level - 1) id
\r
1192 | _, None -> assert false (*error*) in
\r
1193 match ctx.class_context with
\r
1194 | ForContext (ctx, _) | FunctionEvaluationContext (ctx, _, _) ->
\r
1195 evaluate_local_identifier ctx level id
\r
1196 | InstanceContext inst -> evaluate_local_identifier' ctx inst level
\r
1197 | ToplevelContext -> assert false (*error*)
\r
1199 and evaluate_loop_variable ctx level =
\r
1200 let rec evaluate_loop_variable' ctx level' =
\r
1201 match level', ctx.class_context with
\r
1202 | 0, ForContext (_, None) -> assert false (*LoopVariable level'*)
\r
1203 | 0, ForContext (_, Some expr) -> expr
\r
1204 | _, ForContext (ctx, _) -> evaluate_loop_variable ctx (level' - 1)
\r
1205 | _, FunctionEvaluationContext (ctx, _, _) ->
\r
1206 evaluate_loop_variable' ctx level'
\r
1207 | _, (InstanceContext _ | ToplevelContext) -> assert false (*error*) in
\r
1208 evaluate_loop_variable' ctx level
\r
1210 and evaluate_no_event ctx expr =
\r
1211 let expr = evaluate_expression ctx expr in
\r
1213 | True | False | Integer _ | Real _ | String _ | EnumerationElement _ ->
\r
1215 | _ -> NoEvent expr
\r
1217 and evaluate_range ctx start step stop =
\r
1218 let start = evaluate_expression ctx start
\r
1219 and step = evaluate_expression ctx step
\r
1220 and stop = evaluate_expression ctx stop in
\r
1221 let real_of_expression expr = match expr with
\r
1223 | Integer i -> Int32.to_float i
\r
1224 | _ -> assert false in
\r
1225 let integer_interval istart istep istop = match istart, istep, istop with
\r
1227 when (Int32.compare istop istart) *
\r
1228 (Int32.compare istep Int32.zero) < 0 ->
\r
1229 Vector (Array.make 0 (Integer istart))
\r
1232 Int32.div (Int32.sub istop istart) istep in
\r
1233 let n' = Int32.to_int (Int32.succ n) in
\r
1235 let i' = Int32.of_int i in
\r
1237 Int32.add istart (Int32.mul i' istep) in
\r
1239 Vector (Array.init n' f)
\r
1240 and real_interval rstart rstep rstop = match rstart, rstep, rstop with
\r
1241 | _ when (rstop -. rstart) /. rstep < 0. ->
\r
1242 Vector (Array.make 0 (Real rstart))
\r
1244 let n = truncate ((rstop -. rstart) /. rstep) + 1
\r
1245 and f i = Real (rstart +. float_of_int i *. rstep) in
\r
1246 Vector (Array.init n f) in
\r
1247 match start, step, stop with
\r
1248 | _, Integer istep, _
\r
1249 when Int32.compare istep Int32.zero = 0 ->
\r
1250 raise (InstantError
\r
1251 {err_msg = ["_RangeStepValueCannotBeNull"];
\r
1254 | _, Real rstep, _ when rstep = 0. ->
\r
1255 raise (InstantError
\r
1256 {err_msg = ["_RangeStepValueCannotBeNull"];
\r
1259 | Integer istart, Integer istep, Integer istop ->
\r
1260 integer_interval istart istep istop
\r
1261 | (Integer _ | Real _), (Integer _ | Real _), (Integer _ | Real _) ->
\r
1262 let rstart = real_of_expression start
\r
1263 and rstep = real_of_expression step
\r
1264 and rstop = real_of_expression stop in
\r
1265 real_interval rstart rstep rstop
\r
1266 | _, _, _ -> Range (start, step, stop)
\r
1268 and evaluate_coercion ctx coer expr =
\r
1269 let rec evaluate_real_of_integer expr' = match expr' with
\r
1270 | Integer i -> Real (Int32.to_float i)
\r
1272 Vector (Array.map evaluate_real_of_integer exprs)
\r
1274 let expr' = evaluate_expression ctx expr in
\r
1276 | NameResolve.RealOfInteger -> evaluate_real_of_integer expr'
\r
1278 and evaluate_toplevel_identifier ctx id =
\r
1279 let elt_desc = List.assoc id (evaluate ctx.toplevel) in
\r
1280 match evaluate elt_desc.element_nature with
\r
1281 | Class cl_def -> ClassReference cl_def
\r
1282 | Component cpnt_desc -> ComponentReference cpnt_desc
\r
1284 and evaluate_tuple ctx exprs =
\r
1285 Tuple (List.map (evaluate_expression ctx) exprs)
\r
1287 and evaluate_unary_operation ctx unop expr =
\r
1288 let expr = evaluate_expression ctx expr in
\r
1289 let expr = flatten_expression expr in
\r
1291 | NameResolve.Not -> evaluate_not expr
\r
1292 | NameResolve.UnaryMinus -> evaluate_unary_minus expr
\r
1293 | NameResolve.UnaryPlus -> expr
\r
1295 (*and evaluate_vector_reduction ctx ranges expr =
\r
1296 let rec evaluate_vector_reduction' ctx = function
\r
1297 | [] -> evaluate_expression ctx expr
\r
1298 | ranges -> vector_of_reduction ctx ranges
\r
1299 and vector_of_reduction ctx = function
\r
1300 | Range (Integer start, Integer step, Integer stop) :: ranges ->
\r
1301 vector_of_range ctx start step stop ranges
\r
1305 class_context = ForContext (ctx, None)
\r
1307 VectorReduction (ranges, evaluate_expression ctx' expr)
\r
1308 and vector_of_range ctx start step stop ranges =
\r
1309 let rec expression_list pred start = match pred start with
\r
1314 class_context = ForContext (ctx, Some (Integer start))
\r
1316 let expr = evaluate_vector_reduction' ctx' ranges in
\r
1317 expr :: expression_list pred (Int32.add start step) in
\r
1318 let cmp = Int32.compare step 0l in
\r
1320 | 0 when Int32.compare start stop <> 0 -> assert false (*error*)
\r
1321 | 0 -> Vector [||]
\r
1322 | _ when cmp < 0 ->
\r
1323 let pred = function i -> Int32.compare i stop < 0 in
\r
1324 let exprs = expression_list pred start in
\r
1325 Vector (Array.of_list exprs)
\r
1327 let pred = function i -> Int32.compare i stop > 0 in
\r
1328 let exprs = expression_list pred start in
\r
1329 Vector (Array.of_list exprs) in
\r
1330 let ranges = List.map (evaluate_expression ctx) ranges in
\r
1331 evaluate_vector_reduction' ctx ranges*)
\r
1333 and evaluate_vector_reduction ctx ranges expr =
\r
1334 let rec evaluate_vector_reduction' ctx = function
\r
1335 | [] -> evaluate_expression ctx expr
\r
1336 | ranges -> vector_of_reduction ctx ranges
\r
1337 and vector_of_reduction ctx = function
\r
1338 | Range (Integer u, Integer p, Integer v) :: ranges ->
\r
1339 vector_of_integer_range ctx u p v ranges
\r
1340 | Range (Real u, Real p, Real v) :: ranges ->
\r
1341 vector_of_real_range ctx u p v ranges
\r
1342 | Vector exprs :: ranges ->
\r
1346 class_context = ForContext (ctx, Some exprs.(i))
\r
1348 evaluate_vector_reduction' ctx' ranges in
\r
1349 Vector (Array.init (Array.length exprs) f)
\r
1350 | _ -> assert false
\r
1351 and vector_of_integer_range ctx start step stop ranges =
\r
1352 let rec expression_list pred start = match pred start with
\r
1355 let expr = Integer start in
\r
1359 ForContext (ctx, Some expr)
\r
1361 let expr = evaluate_vector_reduction' ctx' ranges in
\r
1362 let next = Int32.add start step in
\r
1363 expr :: expression_list pred next in
\r
1365 | _ when Int32.compare step Int32.zero = 0 ->
\r
1366 raise (InstantError
\r
1367 {err_msg = ["_RangeStepValueCannotBeNull"];
\r
1370 | _ when Int32.compare step Int32.zero < 0 ->
\r
1371 let pred = function i -> (Int32.compare i stop < 0) in
\r
1372 Vector (Array.of_list (expression_list pred start))
\r
1374 let pred = function i -> (Int32.compare i stop > 0) in
\r
1375 Vector (Array.of_list (expression_list pred start))
\r
1376 and vector_of_real_range ctx start step stop ranges =
\r
1377 let rec expression_list pred start = match pred start with
\r
1380 let expr = Real start in
\r
1383 class_context = ForContext (ctx, Some expr)
\r
1385 let expr = evaluate_vector_reduction' ctx' ranges in
\r
1386 expr :: expression_list pred (start +. step) in
\r
1389 raise (InstantError
\r
1390 {err_msg = ["_RangeStepValueCannotBeNull"];
\r
1393 | _ when step < 0. ->
\r
1394 let pred = function f -> f < stop in
\r
1395 Vector (Array.of_list (expression_list pred start))
\r
1397 let pred = function f -> f > stop in
\r
1398 Vector (Array.of_list (expression_list pred start)) in
\r
1399 let ranges = List.map (evaluate_expression ctx) ranges in
\r
1400 evaluate_vector_reduction' ctx ranges
\r
1402 and evaluate_vector ctx exprs =
\r
1403 let exprs = List.map (evaluate_expression ctx) exprs in
\r
1404 Vector (Array.of_list exprs)
\r
1406 and evaluate_and expr expr' = match expr, expr' with
\r
1407 | False, (False | True) | True, False -> False
\r
1408 | True, True -> True
\r
1409 | Vector exprs, Vector exprs' ->
\r
1410 Vector (ArrayExt.map2 evaluate_and exprs exprs')
\r
1411 | _ -> BinaryOperation (And, expr, expr')
\r
1413 and evaluate_divide ctx expr expr' = match expr, expr' with
\r
1414 | _, Integer 0l ->
\r
1415 raise (InstantError
\r
1416 { err_msg = ["_DivisionByZero"];
\r
1418 err_ctx = ctx }) (*error*)
\r
1419 | Integer 0l, _ -> Integer 0l
\r
1420 | Integer i, Integer i' ->
\r
1421 Real ((Int32.to_float i) /. (Int32.to_float i'))
\r
1423 raise (InstantError
\r
1424 { err_msg = ["_DivisionByZero"];
\r
1426 err_ctx = ctx }) (*error*)
\r
1427 | Integer i, Real f -> Real (Int32.to_float i /. f)
\r
1428 | Real f, Integer i -> Real (f /. Int32.to_float i)
\r
1429 | Real f, Real f' -> Real (f /. f')
\r
1430 | Vector exprs, _ ->
\r
1431 let divide_element expr = evaluate_divide ctx expr expr' in
\r
1432 Vector (Array.map divide_element exprs)
\r
1433 | _ -> BinaryOperation (Divide, expr, expr')
\r
1435 and evaluate_equalequal expr expr' = match expr, expr' with
\r
1436 | Integer i, Integer i' when i = i' -> True
\r
1437 | Integer i, Real f | Real f, Integer i when f = Int32.to_float i -> True
\r
1438 | Real f, Real f' when f = f' -> True
\r
1439 | (Integer _ | Real _), (Integer _ | Real _) -> False
\r
1440 | Vector exprs, Vector exprs'
\r
1443 (fun expr expr' -> evaluate_equalequal expr expr' = True)
\r
1446 | Vector _, Vector _ -> False
\r
1447 | _ -> BinaryOperation (EqualEqual, expr, expr')
\r
1449 and evaluate_greater_equal expr expr' = match expr, expr' with
\r
1450 | Integer i, Integer i' when i >= i' -> True
\r
1451 | Integer i, Real f when Int32.to_float i >= f -> True
\r
1452 | Real f, Integer i when f >= Int32.to_float i -> True
\r
1453 | Real f, Real f' when f >= f' -> True
\r
1454 | (Integer _ | Real _), (Integer _ | Real _) -> False
\r
1455 | _ -> BinaryOperation (GreaterEqual, expr, expr')
\r
1457 and evaluate_greater expr expr' = match expr, expr' with
\r
1458 | Integer i, Integer i' when i > i' -> True
\r
1459 | Integer i, Real f when Int32.to_float i > f -> True
\r
1460 | Real f, Integer i when f > Int32.to_float i -> True
\r
1461 | Real f, Real f' when f > f' -> True
\r
1462 | (Integer _ | Real _), (Integer _ | Real _) -> False
\r
1463 | _ -> BinaryOperation (Greater, expr, expr')
\r
1465 and evaluate_less_equal expr expr' = match expr, expr' with
\r
1466 | Integer i, Integer i' when i <= i' -> True
\r
1467 | Integer i, Real f when Int32.to_float i <= f -> True
\r
1468 | Real f, Integer i when f <= Int32.to_float i -> True
\r
1469 | Real f, Real f' when f <= f' -> True
\r
1470 | (Integer _ | Real _), (Integer _ | Real _) -> False
\r
1471 | _ -> BinaryOperation (LessEqual, expr, expr')
\r
1473 and evaluate_less expr expr' = match expr, expr' with
\r
1474 | Integer i, Integer i' when i < i' -> True
\r
1475 | Integer i, Real f when Int32.to_float i < f -> True
\r
1476 | Real f, Integer i when f < Int32.to_float i -> True
\r
1477 | Real f, Real f' when f < f' -> True
\r
1478 | (Integer _ | Real _), (Integer _ | Real _) -> False
\r
1479 | _ -> BinaryOperation (Less, expr, expr')
\r
1481 and evaluate_times expr expr' =
\r
1482 let rec line exprs i = match exprs.(i) with
\r
1483 | Vector exprs -> exprs
\r
1484 | _ -> assert false
\r
1485 and column exprs j =
\r
1486 let f i = match exprs.(i) with
\r
1487 | Vector exprs -> exprs.(j)
\r
1488 | _ -> assert false in
\r
1489 Array.init (Array.length exprs) f
\r
1490 and ndims expr = match expr with
\r
1491 | Vector exprs when Array.length exprs = 0 -> assert false
\r
1492 | Vector exprs -> 1 + ndims exprs.(0)
\r
1494 and size expr i = match expr, i with
\r
1495 | _, 0 -> assert false
\r
1496 | Vector exprs, 1 -> Array.length exprs
\r
1498 | Vector exprs, _ when i > 1 -> size exprs.(0) (i - 1)
\r
1499 | _, _ -> assert false
\r
1500 and vector_mult exprs exprs' =
\r
1501 let exprs = ArrayExt.map2 evaluate_times exprs exprs' in
\r
1502 match Array.length exprs with
\r
1503 | 0 -> assert false
\r
1506 let exprs' = Array.sub exprs 1 (n - 1) in
\r
1507 Array.fold_left evaluate_plus exprs.(0) exprs' in
\r
1508 match expr, expr' with
\r
1509 | Integer 0l, _ | _, Integer 0l -> Integer 0l
\r
1510 | Integer 1l, _ -> expr'
\r
1511 | _, Integer 1l -> expr
\r
1512 | Integer i, Integer i' -> Integer (Int32.mul i i')
\r
1513 | Integer i, Real f | Real f, Integer i -> Real (f *. Int32.to_float i)
\r
1514 | Real f, Real f' -> Real (f *. f')
\r
1515 | _, Vector exprs' when (ndims expr = 0) ->
\r
1516 Vector (Array.map (evaluate_times expr) exprs')
\r
1517 | Vector exprs, _ when (ndims expr' = 0) ->
\r
1518 Vector (Array.map (evaluate_times expr') exprs)
\r
1519 | Vector exprs, Vector exprs' when (ndims expr = 1) && (ndims expr' = 1) ->
\r
1520 vector_mult exprs exprs'
\r
1521 | Vector exprs, Vector exprs' when (ndims expr = 1) && (ndims expr' = 2) ->
\r
1522 let f j = vector_mult exprs (column exprs' j) in
\r
1523 Vector (Array.init (size expr' 2) f)
\r
1524 | Vector exprs, Vector exprs' when (ndims expr = 2) && (ndims expr' = 1) ->
\r
1525 let f i = vector_mult (line exprs i) exprs' in
\r
1526 Vector (Array.init (size expr 1) f)
\r
1527 | Vector exprs, Vector exprs' when (ndims expr = 2) && (ndims expr' = 2) ->
\r
1528 let f i j = vector_mult (line exprs i) (column exprs' j) in
\r
1529 let g i = Vector (Array.init (size expr' 2) (f i)) in
\r
1530 Vector (Array.init (size expr 1) g)
\r
1531 | _ -> BinaryOperation (Times, expr, expr')
\r
1533 and evaluate_not_equal expr expr' = match expr, expr' with
\r
1534 | Integer i, Integer i' when i <> i' -> True
\r
1535 | Integer i, Real f | Real f, Integer i when f <> Int32.to_float i -> True
\r
1536 | Real f, Real f' when f <> f' -> True
\r
1537 | (Integer _ | Real _), (Integer _ | Real _) -> False
\r
1538 | Vector exprs, Vector exprs'
\r
1541 (fun expr expr' -> evaluate_equalequal expr expr' = False)
\r
1544 | Vector _, Vector _ -> False
\r
1545 | _ -> BinaryOperation (NotEqual, expr, expr')
\r
1547 and evaluate_or expr expr' = match expr, expr' with
\r
1548 | True, (False | True) | False, True -> True
\r
1549 | False, False -> False
\r
1550 | Vector exprs, Vector exprs' ->
\r
1551 Vector (ArrayExt.map2 evaluate_or exprs exprs')
\r
1552 | _ -> BinaryOperation (Or, expr, expr')
\r
1554 and evaluate_plus expr expr' = match expr, expr' with
\r
1555 | Integer 0l, _ -> expr'
\r
1556 | _, Integer 0l -> expr
\r
1557 | Integer i, Integer i' -> Integer (Int32.add i i')
\r
1558 | Integer i, Real f | Real f, Integer i -> Real (f +. Int32.to_float i)
\r
1559 | Real f, Real f' -> Real (f +. f')
\r
1560 | Vector exprs, Vector exprs' ->
\r
1561 Vector (ArrayExt.map2 evaluate_plus exprs exprs')
\r
1562 | _ -> BinaryOperation (Plus, expr, expr')
\r
1564 and evaluate_power ctx expr expr' =
\r
1565 match expr, expr' with
\r
1566 | (Integer 0l | Real 0.), (Integer 0l | Real 0.) ->
\r
1567 raise (InstantError
\r
1568 { err_msg = ["_ZeroRaisedToTheZeroPower"];
\r
1570 err_ctx = ctx }) (*error*)
\r
1571 | (Integer 0l | Real 0.), Integer i'
\r
1572 when Int32.compare i' 0l < 0 ->
\r
1573 raise (InstantError
\r
1574 { err_msg = ["_ZeroRaisedToNegativePower"];
\r
1576 err_ctx = ctx }) (*error*)
\r
1577 | (Integer 0l | Real 0.), Real f' when f' < 0. ->
\r
1578 raise (InstantError
\r
1579 { err_msg = ["_ZeroRaisedToNegativePower"];
\r
1581 err_ctx = ctx }) (*error*)
\r
1582 | Integer 0l, Integer _ ->
\r
1583 (* We know the answer for sure since second argument is constant *)
\r
1585 | (Integer 0l | Real 0.), (Integer _ | Real _) -> Real 0.
\r
1586 | Integer i, Real _ when Int32.compare i 0l < 0 ->
\r
1587 raise (InstantError
\r
1588 { err_msg = ["_RealExponentOfNegativeNumber"];
\r
1590 err_ctx = ctx }) (*error*)
\r
1591 | Real f, Real _ when f < 0. ->
\r
1592 raise (InstantError
\r
1593 { err_msg = ["_RealExponentOfNegativeNumber"];
\r
1595 err_ctx = ctx }) (*error*)
\r
1596 | Integer i, Integer i' ->
\r
1597 Real ((Int32.to_float i) ** (Int32.to_float i'))
\r
1598 | Integer i, Real f -> Real ((Int32.to_float i) ** f)
\r
1599 | Real f, Integer i' -> Real (f ** (Int32.to_float i'))
\r
1600 | Real f, Real f' -> Real (f ** f')
\r
1601 | Vector exprs, Integer i ->
\r
1602 raise (InstantError
\r
1603 { err_msg = ["_NotYetImplemented";
\r
1604 "_VectorRaisedToIntegerPower"];
\r
1607 | _ -> BinaryOperation (Power, expr, expr')
\r
1609 and evaluate_minus expr expr' = match expr, expr' with
\r
1610 | Integer 0l, _ -> evaluate_unary_minus expr'
\r
1611 | _, Integer 0l -> expr
\r
1612 | Integer i, Integer i' -> Integer (Int32.sub i i')
\r
1613 | Integer i, Real f -> Real (Int32.to_float i -. f)
\r
1614 | Real f, Integer i -> Real (f -. Int32.to_float i)
\r
1615 | Real f, Real f' -> Real (f -. f')
\r
1616 | Vector exprs, Vector exprs' ->
\r
1617 Vector (ArrayExt.map2 evaluate_minus exprs exprs')
\r
1618 | _ -> BinaryOperation (Minus, expr, expr')
\r
1620 and evaluate_class_function_invocation cl_def exprs =
\r
1621 FunctionCall (ClassReference cl_def, exprs)
\r
1623 and evaluate_predefined_function_invocation ctx s exprs =
\r
1624 match s, exprs with
\r
1625 | "size", _ -> evaluate_size exprs
\r
1626 | "reinit", [expr; expr'] -> evaluate_reinit expr expr'
\r
1627 | "der", [expr] -> evaluate_der expr
\r
1628 | "pre", [expr] -> evaluate_pre expr
\r
1629 | ("edge" | "change" | "initial" | "terminal" | "sample" |
\r
1630 "delay" | "assert" | "terminate"), _ ->
\r
1631 raise (InstantError
\r
1632 { err_msg = ["_NotYetImplemented"; "_PredefinedOperator"; s];
\r
1634 err_ctx = ctx}) (*error*)
\r
1635 | "abs", [expr] -> evaluate_abs expr
\r
1636 | "sign", [expr] -> evaluate_sign expr
\r
1637 | "cos", [expr] -> evaluate_cos expr
\r
1638 | "sin", [expr] -> evaluate_sin expr
\r
1639 | "tan", [expr] -> evaluate_tan expr
\r
1640 | "exp", [expr] -> evaluate_exp expr
\r
1641 | "log", [expr] -> evaluate_log expr
\r
1642 | "sqrt", [expr] -> evaluate_sqrt expr
\r
1643 | "asin", [expr] -> evaluate_asin expr
\r
1644 | "acos", [expr] -> evaluate_acos expr
\r
1645 | "atan", [expr] -> evaluate_atan expr
\r
1646 | "sinh", [expr] -> evaluate_sinh expr
\r
1647 | "cosh", [expr] -> evaluate_cosh expr
\r
1648 | "tanh", [expr] -> evaluate_tanh expr
\r
1649 | "asinh", [expr] -> evaluate_asinh expr
\r
1650 | "acosh", [expr] -> evaluate_acosh expr
\r
1651 | "atanh", [expr] -> evaluate_atanh expr
\r
1652 | "log10", [expr] -> evaluate_log10 expr
\r
1653 | "max", [expr; expr'] -> evaluate_max expr expr'
\r
1654 | "min", [expr; expr'] -> evaluate_min expr expr'
\r
1655 | "div", [expr; expr'] -> evaluate_div ctx expr expr'
\r
1656 | "mod", [expr; expr'] -> evaluate_mod expr expr'
\r
1657 | "rem", [expr; expr'] -> evaluate_rem expr expr'
\r
1658 | "ceil", [expr] -> evaluate_ceil expr
\r
1659 | "floor", [expr] -> evaluate_floor expr
\r
1660 | "max", [expr] -> evaluate_max_array expr
\r
1661 | "min", [expr] -> evaluate_min_array expr
\r
1662 | "sum", [expr] -> evaluate_sum expr
\r
1663 | "product", [expr] -> evaluate_product expr
\r
1664 | "scalar", [expr] -> evaluate_scalar ctx expr
\r
1665 | "ones", exprs -> evaluate_ones ctx exprs
\r
1666 | "zeros", exprs -> evaluate_zeros ctx exprs
\r
1667 | "fill", expr :: exprs -> evaluate_fill ctx expr exprs
\r
1668 | "identity", [expr] -> evaluate_identity ctx expr
\r
1669 | "diagonal", [expr] -> evaluate_diagonal ctx expr
\r
1670 | "vector", [ expr ] -> evaluate_vector_operator ctx expr
\r
1671 | "matrix", [ expr ] -> evaluate_matrix_operator ctx expr
\r
1672 | "transpose", [ expr ] -> evaluate_transpose expr
\r
1673 | "symmetric", [ expr ] -> evaluate_symmetric ctx expr
\r
1675 raise (InstantError
\r
1676 { err_msg = ["_UnknownFunction"; s];
\r
1678 err_ctx = ctx}) (*error*)
\r
1680 and evaluate_symmetric ctx expr = match expr with
\r
1681 | Vector [||] -> assert false
\r
1682 | Vector exprs when size exprs.(0) 0 <> Array.length exprs ->
\r
1683 raise (InstantError
\r
1684 { err_msg = ["_InvalidArgOfOper"; "symmetric"];
\r
1686 err_ctx = ctx }) (*error*)
\r
1689 if i > j then element i (element j expr)
\r
1690 else element j (element i expr) in
\r
1691 let n = Array.length exprs in
\r
1692 let g i = Vector (Array.init n (f i)) in
\r
1693 Vector (Array.init n g)
\r
1694 | _ -> assert false
\r
1696 and evaluate_transpose expr =
\r
1699 let f i = Vector (Array.map (element i) exprs) in
\r
1700 Vector (Array.init (size expr 1) f)
\r
1701 | _ -> assert false
\r
1703 and evaluate_matrix_operator ctx expr =
\r
1704 let rec scalar expr = match expr with
\r
1705 | Vector [| expr |] -> scalar expr
\r
1707 raise (InstantError
\r
1708 { err_msg = ["_InvalidArgOfOper"; "matrix"];
\r
1710 err_ctx = ctx }) (*error*)
\r
1713 | _ when ndims expr < 2 ->
\r
1714 evaluate_promote ctx 2 expr
\r
1715 | _ when ndims expr = 2 -> expr
\r
1717 let f expr = Vector (Array.map scalar (array_elements expr)) in
\r
1718 Vector (Array.map f exprs)
\r
1719 | _ -> assert false
\r
1721 and evaluate_promote ctx n expr =
\r
1722 let rec evaluate_promote' i expr =
\r
1724 | _ when i = 0 -> expr
\r
1725 | Vector exprs when i > 0 ->
\r
1726 Vector (Array.map (evaluate_promote' i) exprs)
\r
1728 Vector [| evaluate_promote' (i - 1) expr |]
\r
1729 | _ -> assert false in
\r
1730 match ndims expr with
\r
1731 | n' when n' < n ->
\r
1732 evaluate_promote' (n - n') expr
\r
1735 and evaluate_vector_operator ctx expr =
\r
1736 let rec evaluate_scalar expr = match expr with
\r
1737 | Vector [| expr |] -> evaluate_scalar expr
\r
1739 raise (InstantError
\r
1740 { err_msg = ["_InvalidArgOfOper"; "vector"];
\r
1742 err_ctx = ctx }) (*error*)
\r
1744 and evaluate_vector_operator' expr = match expr with
\r
1745 | Vector [| expr |] -> evaluate_vector_operator' expr
\r
1747 Array.map evaluate_scalar exprs
\r
1748 | _ -> [| expr |] in
\r
1749 Vector (evaluate_vector_operator' expr)
\r
1751 and evaluate_max_array expr =
\r
1752 let rec evaluate_max_list exprs = match exprs with
\r
1753 | [] -> assert false
\r
1754 | [ expr ] -> expr
\r
1755 | expr :: exprs ->
\r
1756 evaluate_max expr (evaluate_max_list exprs) in
\r
1757 evaluate_max_list (scalar_elements expr)
\r
1759 and evaluate_min_array expr =
\r
1760 let rec evaluate_min_list exprs = match exprs with
\r
1761 | [] -> assert false
\r
1762 | [ expr ] -> expr
\r
1763 | expr :: exprs ->
\r
1764 evaluate_min expr (evaluate_min_list exprs) in
\r
1765 evaluate_min_list (scalar_elements expr)
\r
1767 and evaluate_sum expr =
\r
1768 let rec evaluate_sum_list exprs = match exprs with
\r
1769 | [] -> Integer Int32.zero
\r
1770 | [ expr ] -> expr
\r
1771 | expr :: exprs ->
\r
1772 evaluate_plus expr (evaluate_sum_list exprs) in
\r
1775 evaluate_sum_list (scalar_elements expr)
\r
1776 | _ -> assert false
\r
1778 and evaluate_product expr =
\r
1779 let rec evaluate_product_list exprs = match exprs with
\r
1780 | [] -> Integer Int32.one
\r
1781 | [ expr ] -> expr
\r
1782 | expr :: exprs ->
\r
1783 evaluate_times expr (evaluate_product_list exprs) in
\r
1786 evaluate_product_list (scalar_elements expr)
\r
1787 | _ -> assert false
\r
1789 and evaluate_fill ctx expr exprs =
\r
1790 let rec evaluate_fill' dims = match dims with
\r
1792 | Integer i :: dims when Int32.compare i Int32.zero > 0 ->
\r
1793 let i = Int32.to_int i in
\r
1794 Vector (Array.make i (evaluate_fill' dims))
\r
1796 raise (InstantError
\r
1797 { err_msg = ["_InvalidArgOfOper"; "fill"];
\r
1799 err_ctx = ctx }) (*error*) in
\r
1800 evaluate_fill' exprs
\r
1802 and evaluate_zeros ctx exprs =
\r
1803 let rec evaluate_zeros' dims = match dims with
\r
1804 | [] -> Integer Int32.zero
\r
1805 | Integer i :: dims when Int32.compare i Int32.zero > 0 ->
\r
1806 let i = Int32.to_int i in
\r
1807 Vector (Array.make i (evaluate_zeros' dims))
\r
1809 raise (InstantError
\r
1810 { err_msg = ["_InvalidArgOfOper"; "zeros"];
\r
1812 err_ctx = ctx }) (*error*) in
\r
1813 evaluate_zeros' exprs
\r
1815 and evaluate_ones ctx exprs =
\r
1816 let rec evaluate_ones' dims = match dims with
\r
1817 | [] -> Integer Int32.one
\r
1818 | Integer i :: dims when Int32.compare i Int32.zero > 0 ->
\r
1819 let i = Int32.to_int i in
\r
1820 Vector (Array.make i (evaluate_ones' dims))
\r
1822 raise (InstantError
\r
1823 { err_msg = ["_InvalidArgOfOper"; "ones"];
\r
1825 err_ctx = ctx }) (*error*) in
\r
1826 evaluate_ones' exprs
\r
1828 and evaluate_identity ctx expr =
\r
1829 let n = match expr with
\r
1830 | Integer i when Int32.compare i Int32.zero > 0 ->
\r
1833 raise (InstantError
\r
1834 { err_msg = ["_InvalidArgOfOper"; "identity"];
\r
1836 err_ctx = ctx }) (*error*) in
\r
1838 Integer (if j = i then Int32.one else Int32.zero) in
\r
1839 let g i = Vector (Array.init n (f i)) in
\r
1840 Vector (Array.init n g)
\r
1842 and evaluate_diagonal ctx expr =
\r
1843 let exprs = match expr with
\r
1845 raise (InstantError
\r
1846 { err_msg = ["_InvalidArgOfOper"; "diagonal"];
\r
1848 err_ctx = ctx }) (*error*)
\r
1849 | Vector exprs -> exprs
\r
1851 raise (InstantError
\r
1852 { err_msg = ["_InvalidArgOfOper"; "diagonal"];
\r
1854 err_ctx = ctx }) (*error*) in
\r
1855 let n = Array.length exprs in
\r
1857 if j = i then exprs.(i) else Integer Int32.zero in
\r
1858 let g i = Vector (Array.init n (f i)) in
\r
1859 Vector (Array.init n g)
\r
1861 and evaluate_scalar ctx expr =
\r
1862 let rec evaluate_scalar' expr = match expr with
\r
1863 | Vector [| expr |] -> evaluate_scalar' expr
\r
1865 raise (InstantError
\r
1866 { err_msg = ["_InvalidArgOfOper"; "scalar"];
\r
1868 err_ctx = ctx }) (*error*)
\r
1871 | Vector [| expr |] -> evaluate_scalar' expr
\r
1873 raise (InstantError
\r
1874 { err_msg = ["_InvalidArgOfOper"; "scalar"];
\r
1876 err_ctx = ctx }) (*error*)
\r
1878 and evaluate_reinit expr expr' = match expr, expr' with
\r
1879 | Vector exprs, Vector exprs' ->
\r
1880 Vector (ArrayExt.map2 evaluate_reinit exprs exprs')
\r
1882 FunctionCall (PredefinedIdentifier "reinit", [ expr; expr' ])
\r
1884 and evaluate_der expr = match expr with
\r
1885 | Integer _ | String _ | Real _ -> Real 0.
\r
1886 | Vector exprs -> Vector (Array.map evaluate_der exprs)
\r
1887 | BinaryOperation (Plus, expr, expr') ->
\r
1888 let expr = evaluate_der expr
\r
1889 and expr' = evaluate_der expr' in
\r
1890 BinaryOperation (Plus, expr, expr')
\r
1891 | BinaryOperation (Minus, expr, expr') ->
\r
1892 let expr = evaluate_der expr
\r
1893 and expr' = evaluate_der expr' in
\r
1894 BinaryOperation (Minus, expr, expr')
\r
1895 | BinaryOperation (Times, expr1, expr2) ->
\r
1896 let expr1' = evaluate_der expr1
\r
1897 and expr2' = evaluate_der expr2 in
\r
1898 let expr1 = BinaryOperation (Times, expr1', expr2)
\r
1899 and expr2 = BinaryOperation (Times, expr1, expr2') in
\r
1900 BinaryOperation (Plus, expr1, expr2)
\r
1901 | BinaryOperation (Divide, expr1, expr2) ->
\r
1902 let expr1' = evaluate_der expr1
\r
1903 and expr2' = evaluate_der expr2 in
\r
1904 let expr1' = BinaryOperation (Times, expr1', expr2)
\r
1905 and expr2' = BinaryOperation (Times, expr1, expr2') in
\r
1906 let expr1 = BinaryOperation (Minus, expr1', expr2')
\r
1907 and expr2 = BinaryOperation (Times, expr2, expr2) in
\r
1908 BinaryOperation (Divide, expr1, expr2)
\r
1909 | BinaryOperation (Power, expr, Integer i) ->
\r
1910 let expr' = evaluate_der expr
\r
1911 and j = Int32.sub i Int32.one in
\r
1912 let expr' = BinaryOperation (Times, Integer i, expr')
\r
1913 and expr = BinaryOperation (Power, expr, Integer j) in
\r
1914 BinaryOperation (Times, expr', expr)
\r
1915 | BinaryOperation (Power, expr, Real f) ->
\r
1916 let expr' = evaluate_der expr
\r
1917 and f' = f -. 1. in
\r
1918 let expr' = BinaryOperation (Times, Real f, expr')
\r
1919 and expr = BinaryOperation (Power, expr, Real f') in
\r
1920 BinaryOperation (Times, expr', expr)
\r
1921 | FunctionCall (PredefinedIdentifier "cos", [ expr ]) ->
\r
1922 let expr' = evaluate_der expr
\r
1923 and expr = FunctionCall (PredefinedIdentifier "sin", [ expr ]) in
\r
1924 let expr = UnaryOperation (UnaryMinus, expr) in
\r
1925 BinaryOperation (Times, expr', expr)
\r
1926 | FunctionCall (PredefinedIdentifier "sin", [ expr ]) ->
\r
1927 let expr' = evaluate_der expr
\r
1928 and expr = FunctionCall (PredefinedIdentifier "cos", [ expr ]) in
\r
1929 BinaryOperation (Times, expr', expr)
\r
1930 | FunctionCall (PredefinedIdentifier "tan", [ expr1 ]) ->
\r
1931 let expr1' = evaluate_der expr1
\r
1932 and expr = BinaryOperation (Times, expr, expr) in
\r
1933 let expr = BinaryOperation (Plus, Real 1., expr) in
\r
1934 BinaryOperation (Times, expr1', expr)
\r
1935 | FunctionCall (PredefinedIdentifier "exp", [ expr1 ]) ->
\r
1936 let expr1' = evaluate_der expr1 in
\r
1937 BinaryOperation (Times, expr1', expr)
\r
1938 | FunctionCall (PredefinedIdentifier "log", [ expr1 ]) ->
\r
1939 let expr1' = evaluate_der expr1 in
\r
1940 BinaryOperation (Divide, expr1', expr)
\r
1941 | FunctionCall (PredefinedIdentifier "sqrt", [ expr1 ]) ->
\r
1942 evaluate_der (BinaryOperation (Power, expr1, Real 0.5))
\r
1943 | FunctionCall (PredefinedIdentifier "asin", [ expr1 ]) ->
\r
1944 let expr1' = evaluate_der expr1 in
\r
1945 let expr1 = BinaryOperation (Times, expr1, expr1) in
\r
1946 let expr1 = BinaryOperation (Minus, Real 1., expr1) in
\r
1947 let expr1 = FunctionCall (PredefinedIdentifier "sqrt", [ expr1 ]) in
\r
1948 BinaryOperation (Divide, expr1', expr1)
\r
1949 | FunctionCall (PredefinedIdentifier "acos", [ expr1 ]) ->
\r
1950 let expr1' = UnaryOperation (UnaryMinus, evaluate_der expr1) in
\r
1951 let expr1 = BinaryOperation (Times, expr1, expr1) in
\r
1952 let expr1 = BinaryOperation (Minus, Real 1., expr1) in
\r
1953 let expr1 = FunctionCall (PredefinedIdentifier "sqrt", [ expr1 ]) in
\r
1954 BinaryOperation (Divide, expr1', expr1)
\r
1955 | FunctionCall (PredefinedIdentifier "atan", [ expr1 ]) ->
\r
1956 let expr1' = evaluate_der expr1 in
\r
1957 let expr1 = BinaryOperation (Times, expr1, expr1) in
\r
1958 let expr1 = BinaryOperation (Plus, Real 1., expr1) in
\r
1959 BinaryOperation (Divide, expr1', expr1)
\r
1960 | FunctionCall (PredefinedIdentifier "sinh", [ expr1 ]) ->
\r
1961 let expr1' = evaluate_der expr1 in
\r
1962 let expr1 = FunctionCall (PredefinedIdentifier "cosh", [ expr1 ]) in
\r
1963 BinaryOperation (Times, expr1', expr1)
\r
1964 | FunctionCall (PredefinedIdentifier "cosh", [ expr1 ]) ->
\r
1965 let expr1' = evaluate_der expr1 in
\r
1966 let expr1 = FunctionCall (PredefinedIdentifier "sinh", [ expr1 ]) in
\r
1967 BinaryOperation (Times, expr1', expr1)
\r
1968 | FunctionCall (PredefinedIdentifier "tanh", [ expr1 ]) ->
\r
1969 let expr1' = evaluate_der expr1 in
\r
1970 let expr1 = BinaryOperation (Times, expr, expr) in
\r
1971 let expr1 = BinaryOperation (Minus, Real 1., expr1) in
\r
1972 BinaryOperation (Times, expr1', expr1)
\r
1973 | FunctionCall (PredefinedIdentifier "asinh", [ expr1 ]) ->
\r
1974 let expr1' = evaluate_der expr1 in
\r
1975 let expr1 = BinaryOperation (Times, expr1, expr1) in
\r
1976 let expr1 = BinaryOperation (Plus, Real 1., expr1) in
\r
1977 let expr1 = FunctionCall (PredefinedIdentifier "sqrt", [ expr1 ]) in
\r
1978 BinaryOperation (Divide, expr1', expr1)
\r
1979 | FunctionCall (PredefinedIdentifier "acosh", [ expr1 ]) ->
\r
1980 let expr1' = evaluate_der expr1 in
\r
1981 let expr1 = BinaryOperation (Times, expr1, expr1) in
\r
1982 let expr1 = BinaryOperation (Minus, expr1, Real 1.) in
\r
1983 let expr1 = FunctionCall (PredefinedIdentifier "sqrt", [ expr1 ]) in
\r
1984 BinaryOperation (Divide, expr1', expr1)
\r
1985 | FunctionCall (PredefinedIdentifier "atanh", [ expr1 ]) ->
\r
1986 let expr1' = evaluate_der expr1 in
\r
1987 let expr1 = BinaryOperation (Times, expr1, expr1) in
\r
1988 let expr1 = BinaryOperation (Minus, expr1, Real 1.) in
\r
1989 BinaryOperation (Divide, expr1', expr1)
\r
1990 | FunctionCall (PredefinedIdentifier "log10", [ expr1 ]) ->
\r
1991 let expr1 = FunctionCall (PredefinedIdentifier "log", [ expr1 ]) in
\r
1992 BinaryOperation (Divide, evaluate_der expr1, Real (log 10.))
\r
1994 (PredefinedIdentifier ("div" | "mod" | "rem" | "ceil" | "floor"), _) ->
\r
1996 | If (alts, default) ->
\r
1998 List.map (function (cond, expr) -> (cond, evaluate_der expr)) alts in
\r
1999 If (alts', evaluate_der default)
\r
2000 | NoEvent expr -> NoEvent (evaluate_der expr)
\r
2001 | UnaryOperation (UnaryMinus, expr) ->
\r
2002 UnaryOperation (UnaryMinus, evaluate_der expr)
\r
2003 | VectorReduction (exprs, expr) ->
\r
2004 VectorReduction (exprs, evaluate_der expr)
\r
2005 | _ -> FunctionCall (PredefinedIdentifier "der", [ expr ])
\r
2007 and evaluate_pre expr = match expr with
\r
2009 Vector (Array.map evaluate_pre exprs)
\r
2011 FunctionCall (PredefinedIdentifier "pre", [ expr ])
\r
2013 and evaluate_cos expr = match expr with
\r
2015 Vector (Array.map evaluate_cos exprs)
\r
2017 FunctionCall (PredefinedIdentifier "cos", [ expr ])
\r
2019 and evaluate_sin expr = match expr with
\r
2021 Vector (Array.map evaluate_sin exprs)
\r
2023 FunctionCall (PredefinedIdentifier "sin", [ expr ])
\r
2025 and evaluate_tan expr = match expr with
\r
2027 Vector (Array.map evaluate_tan exprs)
\r
2029 FunctionCall (PredefinedIdentifier "tan", [ expr ])
\r
2031 and evaluate_exp expr = match expr with
\r
2033 Vector (Array.map evaluate_exp exprs)
\r
2035 FunctionCall (PredefinedIdentifier "exp", [ expr ])
\r
2037 and evaluate_log expr = match expr with
\r
2039 Vector (Array.map evaluate_log exprs)
\r
2041 FunctionCall (PredefinedIdentifier "log", [ expr ])
\r
2043 and evaluate_sqrt expr = match expr with
\r
2045 Vector (Array.map evaluate_sqrt exprs)
\r
2047 FunctionCall (PredefinedIdentifier "sqrt", [ expr ])
\r
2049 and evaluate_asin expr = match expr with
\r
2051 Vector (Array.map evaluate_asin exprs)
\r
2053 FunctionCall (PredefinedIdentifier "asin", [ expr ])
\r
2055 and evaluate_acos expr = match expr with
\r
2057 Vector (Array.map evaluate_acos exprs)
\r
2059 FunctionCall (PredefinedIdentifier "acos", [ expr ])
\r
2061 and evaluate_atan expr = match expr with
\r
2063 Vector (Array.map evaluate_atan exprs)
\r
2065 FunctionCall (PredefinedIdentifier "atan", [ expr ])
\r
2067 and evaluate_sinh expr = match expr with
\r
2069 Vector (Array.map evaluate_sinh exprs)
\r
2071 FunctionCall (PredefinedIdentifier "sinh", [ expr ])
\r
2073 and evaluate_cosh expr = match expr with
\r
2075 Vector (Array.map evaluate_cosh exprs)
\r
2077 FunctionCall (PredefinedIdentifier "cosh", [ expr ])
\r
2079 and evaluate_tanh expr = match expr with
\r
2081 Vector (Array.map evaluate_tanh exprs)
\r
2083 FunctionCall (PredefinedIdentifier "tanh", [ expr ])
\r
2085 and evaluate_asinh expr = match expr with
\r
2087 Vector (Array.map evaluate_asinh exprs)
\r
2089 FunctionCall (PredefinedIdentifier "asinh", [ expr ])
\r
2091 and evaluate_acosh expr = match expr with
\r
2093 Vector (Array.map evaluate_acosh exprs)
\r
2095 FunctionCall (PredefinedIdentifier "acosh", [ expr ])
\r
2097 and evaluate_atanh expr = match expr with
\r
2099 Vector (Array.map evaluate_atanh exprs)
\r
2101 FunctionCall (PredefinedIdentifier "atanh", [ expr ])
\r
2103 and evaluate_log10 expr = match expr with
\r
2105 Vector (Array.map evaluate_log10 exprs)
\r
2107 FunctionCall (PredefinedIdentifier "log10", [ expr ])
\r
2109 and evaluate_max expr expr' = match expr, expr' with
\r
2110 | Vector exprs, Vector exprs' ->
\r
2111 Vector (ArrayExt.map2 evaluate_max exprs exprs')
\r
2112 | Real f, Real f' -> Real (max f f')
\r
2114 let b = BinaryOperation (GreaterEqual, expr, expr') in
\r
2115 If ([b, expr], expr')
\r
2117 and evaluate_min expr expr' = match expr, expr' with
\r
2118 | Vector exprs, Vector exprs' ->
\r
2119 Vector (ArrayExt.map2 evaluate_min exprs exprs')
\r
2120 | Real f, Real f' -> Real (min f f')
\r
2122 let b = BinaryOperation (GreaterEqual, expr', expr) in
\r
2123 If ([b, expr], expr')
\r
2125 and evaluate_abs expr = match expr with
\r
2127 Vector (Array.map evaluate_abs exprs)
\r
2128 | Real f -> Real (abs_float f)
\r
2129 | Integer i -> Integer (Int32.abs i)
\r
2131 let b = BinaryOperation (GreaterEqual, expr, Real 0.)
\r
2132 and default = UnaryOperation (UnaryMinus, expr) in
\r
2133 If ([b, expr], default)
\r
2135 and evaluate_sign expr = match expr with
\r
2137 Vector (Array.map evaluate_sign exprs)
\r
2138 | Real f when f > 0. -> Real 1.
\r
2139 | Real f when f < 0. -> Real (-. 1.)
\r
2140 | Real _ -> Real 0.
\r
2141 | Integer i when Int32.compare i Int32.zero > 0 ->
\r
2143 | Integer i when Int32.compare i Int32.zero < 0 ->
\r
2144 Integer Int32.minus_one
\r
2145 | Integer _ -> Integer Int32.zero
\r
2147 let b = BinaryOperation (Greater, expr, Real 0.)
\r
2148 and b' = BinaryOperation (Greater, Real 0., expr) in
\r
2149 If ([(b, Integer Int32.one); (b', Integer Int32.minus_one)],
\r
2150 Integer Int32.zero)
\r
2152 and evaluate_div ctx expr expr' = match expr, expr' with
\r
2153 | Vector exprs, Vector exprs' ->
\r
2154 Vector (ArrayExt.map2 (evaluate_div ctx) exprs exprs')
\r
2156 raise (InstantError
\r
2157 { err_msg = ["_DivisionByZero"];
\r
2159 err_ctx = ctx }) (*error*)
\r
2160 | _, Integer i when i = Int32.zero ->
\r
2161 raise (InstantError
\r
2162 { err_msg = ["_DivisionByZero"];
\r
2164 err_ctx = ctx }) (*error*)
\r
2165 | Integer i, Integer i' -> Integer (Int32.div i i')
\r
2166 | Real f, Integer i' ->
\r
2167 let f' = Int32.to_float i' in
\r
2168 Real (float_of_int (truncate (f /. f')))
\r
2169 | Integer i, Real f' ->
\r
2170 let f = Int32.to_float i in
\r
2171 Real (float_of_int (truncate (f /. f')))
\r
2172 | Real f, Real f' ->
\r
2173 Real (float_of_int (truncate (f /. f')))
\r
2175 FunctionCall (PredefinedIdentifier "div", [ expr; expr' ])
\r
2177 and evaluate_mod expr expr' = match expr, expr' with
\r
2178 | Vector exprs, Vector exprs' ->
\r
2179 Vector (ArrayExt.map2 evaluate_mod exprs exprs')
\r
2181 FunctionCall (PredefinedIdentifier "mod", [ expr; expr' ])
\r
2183 and evaluate_rem expr expr' = match expr, expr' with
\r
2184 | Vector exprs, Vector exprs' ->
\r
2185 Vector (ArrayExt.map2 evaluate_rem exprs exprs')
\r
2187 FunctionCall (PredefinedIdentifier "rem", [ expr; expr' ])
\r
2189 and evaluate_ceil expr = match expr with
\r
2191 Vector (Array.map evaluate_ceil exprs)
\r
2193 FunctionCall (PredefinedIdentifier "ceil", [ expr ])
\r
2195 and evaluate_floor expr = match expr with
\r
2197 Vector (Array.map evaluate_floor exprs)
\r
2199 FunctionCall (PredefinedIdentifier "floor", [ expr ])
\r
2201 and evaluate_size exprs =
\r
2202 let rec evaluate_size' expr i = match expr, i with
\r
2203 | ComponentReference cpnt_desc, _ ->
\r
2204 evaluate_component_size cpnt_desc i
\r
2205 | Vector exprs, 1 -> Integer (Int32.of_int (Array.length exprs))
\r
2206 | Vector exprs, _ -> evaluate_size' exprs.(0) (i - 1)
\r
2207 | _ -> assert false (*error*)
\r
2208 and evaluate_component_size cpnt_desc i =
\r
2209 match evaluate cpnt_desc.component_nature, i with
\r
2210 | DynamicArray _, _ -> FunctionCall (PredefinedIdentifier "size", exprs)
\r
2211 | StaticArray cpnt_descs, 1 ->
\r
2212 Integer (Int32.of_int (Array.length cpnt_descs))
\r
2213 | StaticArray cpnt_descs, _ ->
\r
2214 evaluate_component_size cpnt_descs.(i) (i - 1)
\r
2215 | _ -> assert false (*error*)
\r
2216 and evaluate_size_list = function
\r
2217 | ComponentReference cpnt_desc -> assert false
\r
2219 let size = Integer (Int32.of_int (Array.length exprs)) in
\r
2220 size :: evaluate_size_list exprs.(0)
\r
2223 | [expr] -> Vector (Array.of_list (evaluate_size_list expr))
\r
2224 | [expr; Integer i] -> evaluate_size' expr (Int32.to_int i)
\r
2225 | [expr; _] -> FunctionCall (PredefinedIdentifier "size", exprs)
\r
2226 | _ -> assert false (*error*)
\r
2228 and evaluate_not expr = match expr with
\r
2231 | Vector exprs -> Vector (Array.map evaluate_not exprs)
\r
2232 | _ -> UnaryOperation (Not, expr)
\r
2234 and evaluate_unary_minus expr = match expr with
\r
2235 | Integer i -> Integer (Int32.neg i)
\r
2236 | Real f -> Real (~-. f)
\r
2237 | Vector exprs -> Vector (Array.map evaluate_unary_minus exprs)
\r
2238 | _ -> UnaryOperation (UnaryMinus, expr)
\r
2240 and field_access ctx expr id =
\r
2241 let rec field_access' = function
\r
2242 | ClassReference cl_def ->
\r
2243 let cpnt_desc = create_temporary_instance ctx cl_def in
\r
2244 component_field_access cpnt_desc
\r
2245 | ComponentReference cpnt_desc -> component_field_access cpnt_desc
\r
2246 | Record fields -> List.assoc id fields
\r
2247 | Vector exprs -> Vector (Array.map field_access' exprs)
\r
2248 | _ -> FieldAccess (expr, id)
\r
2249 and component_field_access cpnt_desc =
\r
2250 match evaluate cpnt_desc.component_nature with
\r
2251 | DynamicArray _ -> FieldAccess (expr, id)
\r
2252 | Instance inst -> instance_field_access ctx inst id
\r
2253 | PredefinedTypeInstance _ ->
\r
2254 raise (InstantError
\r
2255 { err_msg = ["_CannotAccessToPredefTypeAttrib"; id];
\r
2257 err_ctx = ctx}) (*error*)
\r
2258 | StaticArray cpnt_descs ->
\r
2259 Vector (Array.map component_field_access cpnt_descs) in
\r
2260 field_access' expr
\r
2262 and instance_field_access ctx inst id =
\r
2263 let evaluate_component cpnt_desc =
\r
2264 let evaluate_declaration_equation = function
\r
2265 | Some expr -> evaluate expr
\r
2267 raise (InstantError
\r
2268 { err_msg = ["_MissingDeclEquForFixedId"; id];
\r
2270 err_ctx = ctx}) (*error*) in
\r
2271 let rec evaluate_parameter cpnt_desc =
\r
2272 let evaluate_predefined_type_instance predef =
\r
2273 match evaluate (List.assoc "fixed" predef.attributes) with
\r
2274 | True -> evaluate_declaration_equation cpnt_desc.declaration_equation
\r
2275 | False -> ComponentReference cpnt_desc
\r
2276 | _ -> assert false (*error*) in
\r
2277 match evaluate cpnt_desc.component_nature with
\r
2278 | PredefinedTypeInstance predef
\r
2279 when List.mem_assoc "fixed" predef.attributes ->
\r
2280 evaluate_predefined_type_instance predef
\r
2281 | DynamicArray cpnt_desc -> assert false
\r
2282 | Instance _ -> ComponentReference cpnt_desc
\r
2283 | PredefinedTypeInstance _ ->
\r
2284 evaluate_declaration_equation cpnt_desc.declaration_equation
\r
2285 | StaticArray cpnt_descs ->
\r
2286 Vector (Array.map evaluate_parameter cpnt_descs)
\r
2288 let decl_equ = cpnt_descs.(i).declaration_equation in
\r
2289 evaluate_declaration_equation decl_equ in
\r
2290 Vector (Array.init (Array.length cpnt_descs) f)*) in
\r
2291 match cpnt_desc.variability with
\r
2292 | Types.Constant ->
\r
2293 evaluate_declaration_equation cpnt_desc.declaration_equation
\r
2294 | Types.Parameter -> evaluate_parameter cpnt_desc
\r
2295 | _ -> ComponentReference cpnt_desc in
\r
2296 let elts = evaluate inst.elements in
\r
2297 let elt_desc = List.assoc id elts.named_elements in
\r
2298 match evaluate elt_desc.element_nature with
\r
2299 | Class cl_def -> ClassReference cl_def
\r
2300 | Component cpnt_desc -> evaluate_component cpnt_desc
\r
2302 and expression_location ctx expr =
\r
2303 match expr.NameResolve.info.NameResolve.syntax with
\r
2304 | None -> ctx.location
\r
2305 | Some expr -> expr.Syntax.info
\r
2307 and class_name_of_component cpnt_desc =
\r
2308 let type_spec = Lazy.force cpnt_desc.NameResolve.type_specifier in
\r
2309 let expr_info = type_spec.NameResolve.info in
\r
2310 match expr_info.NameResolve.syntax with
\r
2312 | Some expr -> Syntax.string_of_expression expr
\r
2314 and instance_nature_of_element elt_desc =
\r
2315 match elt_desc.NameResolve.element_nature with
\r
2316 | NameResolve.Component cpnt_desc ->
\r
2317 ComponentElement (class_name_of_component cpnt_desc)
\r
2318 | _ -> ClassElement
\r
2320 and instance_class_name instance_nature =
\r
2321 match instance_nature with
\r
2322 | ComponentElement s -> s
\r
2323 | ClassElement -> ""
\r
2325 and flatten_expression expr =
\r
2326 let rec flatten_component cpnt_desc =
\r
2327 match evaluate cpnt_desc.component_nature with
\r
2328 | StaticArray cpnt_descs ->
\r
2329 Vector (Array.map flatten_component cpnt_descs)
\r
2330 | _ -> ComponentReference cpnt_desc in
\r
2332 | ComponentReference cpnt_desc ->
\r
2333 flatten_component cpnt_desc
\r
2336 and size expr i = match expr, i with
\r
2337 | Vector [||], _ -> 0
\r
2338 | Vector exprs, 0 -> Array.length exprs
\r
2339 | Vector exprs, _ when i > 0 -> size exprs.(0) (i - 1)
\r
2340 | _ -> invalid_arg "_IndexOutOfBound"
\r
2343 Array.init (ndims expr) (size expr)
\r
2346 let rec ndims' i expr = match expr with
\r
2347 | Vector [||] -> i + 1
\r
2348 | Vector exprs -> ndims' (i + 1) exprs.(0)
\r
2352 and element i expr = match expr with
\r
2353 | Vector exprs -> exprs.(i)
\r
2354 | _ -> assert false
\r
2356 and array_elements expr = match expr with
\r
2357 | Vector exprs -> exprs
\r
2358 | _ -> assert false
\r
2360 and scalar_elements expr = match expr with
\r
2363 Array.to_list (Array.map scalar_elements exprs) in
\r
2364 List.flatten exprss
\r
2369 and generate_expression oc = function
\r
2370 | BinaryOperation (bin_op, expr, expr') ->
\r
2371 generate_binary_operation oc bin_op expr expr'
\r
2372 | ClassReference cl_def ->
\r
2373 generate_class_reference oc cl_def
\r
2374 | ComponentReference cpnt_desc ->
\r
2375 generate_component_reference oc cpnt_desc
\r
2376 | EnumerationElement _ -> assert false
\r
2377 | False -> assert false
\r
2378 | FieldAccess _ -> assert false
\r
2379 | FunctionCall (expr, exprs) ->
\r
2380 generate_function_call oc expr exprs
\r
2381 | If (alts, expr) -> generate_if oc alts expr
\r
2382 | IndexedAccess _ -> assert false
\r
2383 | Integer i when Int32.to_int i >= 0 ->
\r
2384 Printf.fprintf oc "%ld" i
\r
2386 let expr = Integer (Int32.neg i)
\r
2387 and un_op = UnaryMinus in
\r
2388 generate_unary_operation oc un_op expr
\r
2389 | LoopVariable _ -> Printf.fprintf oc "LoopVariable"
\r
2390 | NoEvent expr -> generate_no_event oc expr
\r
2391 | PredefinedIdentifier id -> Printf.fprintf oc "%s" id
\r
2392 | Range _ -> Printf.fprintf oc "Range"
\r
2394 Printf.fprintf oc "%s" (string_of_float f)
\r
2395 | Record _ -> Printf.fprintf oc "Record"
\r
2396 | String _ -> Printf.fprintf oc "String"
\r
2397 | True -> Printf.fprintf oc "True"
\r
2398 | Tuple _ -> Printf.fprintf oc "Tuple"
\r
2399 | UnaryOperation (un_op, expr) ->
\r
2400 generate_unary_operation oc un_op expr
\r
2402 generate_vector oc exprs
\r
2403 | VectorReduction _ -> Printf.fprintf oc "VectorReduction"
\r
2405 and generate_binary_operation oc bin_op expr expr' =
\r
2406 let string_of_binary_operation_kind = function
\r
2409 | EqualEqual -> "=="
\r
2410 | GreaterEqual -> ">="
\r
2412 | LessEqual -> "<="
\r
2415 | NotEqual -> "<>"
\r
2420 Printf.fprintf oc "(";
\r
2421 generate_expression oc expr;
\r
2422 Printf.fprintf oc " %s " (string_of_binary_operation_kind bin_op);
\r
2423 generate_expression oc expr';
\r
2424 Printf.fprintf oc ")"
\r
2426 and generate_class_reference oc cl_def =
\r
2427 let rec last = function
\r
2428 | [] -> assert false
\r
2430 | [Index _] -> assert false
\r
2431 | _ :: path -> last path in
\r
2432 let generate_external_call ext_call =
\r
2433 match ext_call.NameResolve.nature with
\r
2434 | NameResolve.PrimitiveCall "builtin" ->
\r
2435 Printf.fprintf oc "builtin"
\r
2436 | NameResolve.PrimitiveCall "C" ->
\r
2437 Printf.fprintf oc "PrimitiveCall"
\r
2438 | NameResolve.PrimitiveCall lang -> assert false
\r
2439 | NameResolve.ExternalProcedureCall _ -> assert false in
\r
2440 let generate_long_dscription long_desc =
\r
2441 match evaluate long_desc.NameResolve.external_call with
\r
2442 | None -> assert false
\r
2443 | Some ext_call -> generate_external_call ext_call in
\r
2444 match cl_def.description with
\r
2445 | ClassDescription (_, cl_desc) ->
\r
2446 generate_long_dscription cl_desc.long_description
\r
2447 | PredefinedType _ -> assert false
\r
2449 and generate_component_reference oc cpnt_desc =
\r
2450 let name = ident_of_path cpnt_desc.component_path in
\r
2451 Printf.fprintf oc "%s" name
\r
2453 and generate_function_call oc expr exprs =
\r
2454 generate_expression oc expr;
\r
2455 Printf.fprintf oc "(";
\r
2456 generate_expressions oc exprs;
\r
2457 Printf.fprintf oc ")"
\r
2459 and generate_expressions oc = function
\r
2461 | [expr] -> generate_expression oc expr;
\r
2462 | expr :: exprs ->
\r
2463 generate_expression oc expr;
\r
2464 Printf.fprintf oc ", ";
\r
2465 generate_expressions oc exprs
\r
2467 and generate_if oc alts expr =
\r
2468 let rec generate_alternatives = function
\r
2469 | [] -> Printf.fprintf oc " "; generate_expression oc expr
\r
2470 | (expr, expr') :: alts ->
\r
2471 Printf.fprintf oc "(if ";
\r
2472 generate_expression oc expr;
\r
2473 Printf.fprintf oc " then ";
\r
2474 generate_expression oc expr';
\r
2475 Printf.fprintf oc " else";
\r
2476 generate_alternatives alts;
\r
2477 Printf.fprintf oc ")" in
\r
2478 generate_alternatives alts
\r
2480 and generate_no_event oc expr =
\r
2481 Printf.fprintf oc "noEvent(";
\r
2482 generate_expression oc expr;
\r
2483 Printf.fprintf oc ")"
\r
2485 and generate_unary_operation oc un_op expr =
\r
2486 let string_of_unary_operation_kind = function
\r
2488 | UnaryMinus -> "-" in
\r
2489 Printf.fprintf oc "(%s " (string_of_unary_operation_kind un_op);
\r
2490 generate_expression oc expr;
\r
2491 Printf.fprintf oc ")"
\r
2493 and generate_vector oc exprs =
\r
2494 let exprs' = Array.to_list exprs in
\r
2495 Printf.fprintf oc "{ ";
\r
2496 generate_expressions oc exprs';
\r
2497 Printf.fprintf oc " }"
\r
2499 and last_id path =
\r
2500 let rec last_id' id path = match path with
\r
2502 | (Name id) :: path -> last_id' id path
\r
2503 | (Index _) :: path -> last_id' id path in
\r
2506 and string_of_float f =
\r
2507 let add_parenthesis s =
\r
2508 if String.contains s '-' then Printf.sprintf "(%s)" s else s in
\r
2509 match Printf.sprintf "%.16g" f with
\r
2510 | s when (String.contains s '.') || (String.contains s 'e') ->
\r
2512 | s -> add_parenthesis (Printf.sprintf "%s." s)
\r
2514 and ident_of_path path =
\r
2515 let rec ident_of_path' path =
\r
2517 | [] -> assert false
\r
2519 | [Index i] -> Printf.sprintf "[%d]" (i + 1)
\r
2520 | Name id :: path ->
\r
2521 Printf.sprintf "%s.%s" id (ident_of_path' path)
\r
2522 | Index i :: path ->
\r
2523 Printf.sprintf "[%d].%s" (i + 1) (ident_of_path' path) in
\r
2525 | [] -> assert false
\r
2526 | [Name id] -> assert false
\r
2527 | [Index i] -> assert false
\r
2528 | Name id :: path ->
\r
2529 Printf.sprintf "`%s`" (ident_of_path' path)
\r
2530 | Index i :: path -> assert false
\r