Skip to content

Commit dfeb622

Browse files
author
Peter Aronsson
committed
Added addComponent function.
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@790 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent cf46470 commit dfeb622

File tree

3 files changed

+139
-6
lines changed

3 files changed

+139
-6
lines changed

modeq/absyn.rml

Lines changed: 127 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ module Absyn:
275275

276276

277277
relation update_program: (Program,Program) => Program
278+
relation add_component: (string,ComponentRef,ComponentRef,NamedArg list, Program) => (Program,string)
278279
relation path_string : Path => string
279280
relation cref_to_path : ComponentRef => Path
280281
relation element_spec_name : ElementSpec => Ident
@@ -323,6 +324,51 @@ relation update_program: (Program,Program) => Program =
323324
update_program (a,b) => b
324325
end
325326

327+
(** relation add_component
328+
** This relation takes: arg1 - string giving the instancename, arg2 - `ComponentRef' giving the component type
329+
** arg3 - ComponentRef giving the model to instantiate the component within, arg4 - `NamedArg' list of annotations
330+
** and arg5 - a Program. The result is an updated program with the component and its annotations inserted, and a string
331+
** "OK" for success. If the insertion fails, a suitable error string is given along with the input Program.
332+
**)
333+
relation add_component: (string, ComponentRef,ComponentRef,NamedArg list, Program) => (Program ,string) =
334+
335+
rule cref_to_path(model) => modelpath &
336+
path_in_program(modelpath,p) => false
337+
---------------------------------
338+
add_component (name,tp,model,annlst,p) => (p,"Error, No such model\n")
339+
340+
rule cref_to_path(model) => modelpath &
341+
get_pathed_class_in_program(modelpath,p) => cdef &
342+
cref_to_path(tp) => tppath &
343+
annotation_list_to_absyn(annlst) => annotation &
344+
add_to_public(cdef,ELEMENTITEM(ELEMENT(false,UNSPECIFIED,"",
345+
COMPONENTS(ATTR(false,VAR,BIDIR,[NOSUB]),tppath,
346+
[COMPONENTITEM(COMPONENT(name,[],NONE),SOME(annotation))])))) => newcdef &
347+
update_program(PROGRAM([newcdef],w),p)=> newp
348+
------------------------------------------------
349+
add_component( name,tp,model,annlst,p as PROGRAM(_,w)) => (newp,"Ok\n")
350+
351+
axiom add_component (_,_,_,_,p) => (p,"Not implemented yet\n")
352+
353+
end
354+
355+
(** relation: add_to_public
356+
** This relation takes a 'Class' definition and adds an `ElementItem' to the first public list in the class.
357+
** If no public list is available in the class one is created.
358+
**)
359+
relation add_to_public: (Class, ElementItem) => Class =
360+
361+
rule get_public_list(parts) => publst &
362+
let publst2 = eitem::publst &
363+
replace_public_list(parts,publst2) => parts2
364+
--------------------------------------------
365+
add_to_public ( CLASS(i,p,r,PARTS(parts)), eitem) => CLASS(i,p,r,PARTS(parts2))
366+
367+
axiom add_to_public ( CLASS(i,p,r,DERIVED(_,_,_)),eitem) => fail
368+
369+
axiom add_to_public(CLASS(i,p,r,PARTS(parts)),eitem) => CLASS(i,p,r,PARTS(PUBLIC([eitem])::parts))
370+
371+
end
326372
(** relation: replace_class_in_program
327373
** This relation takes a `Class' and a `Program' and replaces the class definition
328374
** at the top level in the program by the class definition of the `Class'.
@@ -446,7 +492,7 @@ end
446492

447493
(** relation: get_inner_class
448494
** This relation takes a class name and a class and return the inner class definition
449-
** having that name
495+
** having that name.
450496
**)
451497
relation get_inner_class: (Class, Ident) => Class =
452498
rule get_public_list(parts) => publst &
@@ -488,7 +534,7 @@ relation get_public_list: ClassPart list => ElementItem list =
488534
---------------------------
489535
get_public_list(x::xs) => ys
490536

491-
axiom get_public_list(_) => []
537+
axiom get_public_list(_) => fail
492538
end
493539

494540
(** relation: get_class_from_elementitemlist
@@ -529,8 +575,43 @@ relation class_in_program:(string,Program) => bool =
529575
axiom class_in_program (_,_) => true
530576
end
531577

578+
(** relation: path_in_program
579+
** This relation takes a path and a program and returns true if the class
580+
** referenced by the path exist in the program
581+
*)
582+
relation path_in_program: (Path, Program) => bool =
583+
584+
rule path_string(path) => pathstr &
585+
class_in_program(pathstr,p) => res
586+
-----------------------------------
587+
path_in_program (path as IDENT(name),p) => res
588+
589+
rule class_in_program(c1,p) => true &
590+
get_class_in_program(c1,p) => c1def &
591+
path_in_program(prest,PROGRAM([c1def],w)) => res
592+
------------------------------------
593+
path_in_program (path as QUALIFIED(c1,prest),p as PROGRAM(_,w)) => res
594+
end
595+
596+
(** relation: get_pathed_class_in_program
597+
** This relation takes a `Path' and a `Program` and retrieves the class definition referenced
598+
** by the `Path' from the `Program'.
599+
*)
600+
relation get_pathed_class_in_program: (Path, Program) => Class =
601+
602+
rule get_class_in_program(str,p) => c1
603+
---------------------------------
604+
get_pathed_class_in_program (IDENT(str),p) => c1
605+
606+
rule
607+
get_class_in_program(c1,p) => c1def &
608+
get_pathed_class_in_program(prest,PROGRAM([c1def],w)) => res
609+
------------------------------------------------------------
610+
get_pathed_class_in_program (path as QUALIFIED(c1,prest),p as PROGRAM(_,w)) => res
611+
end
612+
532613
(** relation: get_class_in_program
533-
** This relation takes a name and a Program and returns the class with the name `name'.
614+
** This relation takes a Path and a Program and returns the class with the name `Path'.
534615
** If that class does not exist, the relation fail
535616
**)
536617

@@ -548,6 +629,49 @@ relation get_class_in_program:(string,Program) => Class =
548629
get_class_in_program (str, PROGRAM((c1 as CLASS(c1name,_,_,_))::p,w)) => c1
549630
end
550631

632+
(** relation: annotation_list_to_absyn
633+
** This relation takes a list of `NamedArg' and returns an absyn `Annotation'.
634+
** for instance [annotation = Placement( ...) ] is converted to ANNOTATION(Placement(...))
635+
**)
636+
relation annotation_list_to_absyn: (NamedArg list) => Annotation =
637+
axiom annotation_list_to_absyn( [] ) => ANNOTATION([])
638+
639+
rule record_constructor_to_modification(e) => eltarg
640+
------------------------------------
641+
annotation_list_to_absyn(NAMEDARG("annotate",e)::_) => ANNOTATION([eltarg])
642+
643+
rule annotation_list_to_absyn(al) => annres
644+
--------------------------------------
645+
annotation_list_to_absyn(a::al) => annres
646+
end
647+
648+
(** relation:record_constructor_to_modification
649+
** This relation takes a record constructor expression and translates it into a `ElementArg'.
650+
** Since modifications must be named, only named arguments are treated in the record constructor.
651+
**)
652+
relation record_constructor_to_modification: (Exp ) => ElementArg =
653+
654+
rule Util.list_map(nargs,namedarg_to_modification) => eltarglst &
655+
let res = MODIFICATION(false,cr,CLASSMOD(eltarglst,NONE))
656+
-----------------------------------
657+
record_constructor_to_modification(CALL(cr,FUNCTIONARGS([],nargs))) => res
658+
end
659+
660+
(** relation: namedarg_to_modification
661+
** This relation takes a `NamedArg' and translates it into a `ElementArg'.
662+
**)
663+
relation namedarg_to_modification: (NamedArg) => ElementArg =
664+
665+
rule record_constructor_to_modification(c) => elt &
666+
let res = MODIFICATION(false,cr,CLASSMOD([elt],NONE))
667+
----------------------------
668+
namedarg_to_modification( NAMEDARG(id,c as CALL(cr,FUNCTIONARGS([],nargs)))) => res
669+
670+
rule let res = MODIFICATION(false,CREF_IDENT(id,[]),CLASSMOD([],SOME(e)))
671+
----------------------------------------------------------------
672+
namedarg_to_modification( NAMEDARG(id,e)) => res
673+
end
674+
551675
(** relation: path_string
552676
**
553677
** This relation simply converts a `Path' to a `string'.

modeq/dump.rml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ relation print_element_arg =
164164
rule print "ARG(" &
165165
print_select(f,"FINAL,",",") &
166166
print_component_ref(r) &
167+
print_modification(m) &
167168
print ")"
168169
-------------------------------------------
169170
print_element_arg(Absyn.MODIFICATION(f,r,m))
@@ -767,7 +768,7 @@ end
767768
relation print_function_args: Absyn.FunctionArgs => () =
768769

769770
rule print "FUNCTIONARGS(" &
770-
print_list_debug("print_exp",expargs,print_exp,", ")
771+
print_list_debug("print_exp",expargs,print_exp,", ") &
771772
print ", " &
772773
print_list_debug("print_namedarg",nargs,print_named_arg,", ") &
773774
print ")"

modeq/interactive.rml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,18 @@ relation evaluate_graphical_api: (InteractiveStmts, InteractiveSymbolTable) =>
105105
Absyn.FUNCTIONARGS([Absyn.STRING(name),Absyn.CREF(cr)],[])))]
106106
),
107107
st as SYMBOLTABLE(p,s,ic,iv)) => (resstr,newst)
108-
108+
109+
110+
rule Absyn.add_component(name,tp,model,annlst,p) => (newp,resstr)
111+
-----------------------
112+
evaluate_graphical_api(
113+
ISTMTS([IEXP(Absyn.CALL(
114+
Absyn.CREF_IDENT("addComponent",_),
115+
Absyn.FUNCTIONARGS([Absyn.STRING(name),Absyn.CREF(tp),Absyn.CREF(model)],annlst)))]
116+
),
117+
st as SYMBOLTABLE(p,s,ic,iv)) => (resstr,SYMBOLTABLE(newp,s,ic,iv))
109118
end
110119

111-
112120
relation componentref_to_path: Absyn.ComponentRef => Absyn.Path =
113121

114122
axiom componentref_to_path(Absyn.CREF_IDENT(ident,_)) => Absyn.IDENT(ident)

0 commit comments

Comments
 (0)