@@ -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
324325end
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'.
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**)
451497relation 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
492538end
493539
494540(** relation: get_class_from_elementitemlist
@@ -529,8 +575,43 @@ relation class_in_program:(string,Program) => bool =
529575 axiom class_in_program (_,_) => true
530576end
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
549630end
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'.
0 commit comments