===
Generic Type Declaration
===

type
  a<b> = x;
  a<b: constraint> = x;
  a<b,c> = x;
  a<b,c: constraint> = x;
  a<b; c: constraint> = x;
  a<b, c: constraint; d,e: constraint> = x;

---

(root
  (declTypes (kType)
    (declType
      (genericTpl 
        (identifier)
        (kLt)
        (genericArgs
          (genericArg
            (identifier)))
        (kGt))
      (kEq)
      (type (typeref (identifier))))
    (declType
      (genericTpl
        (identifier)
        (kLt)
        (genericArgs
          (genericArg
            (identifier) (typeref (identifier))))
        (kGt))
      (kEq)
      (type (typeref (identifier))))
    (declType
      (genericTpl
        (identifier)
        (kLt)
        (genericArgs
          (genericArg (identifier) (identifier)))
        (kGt))
      (kEq)
      (type (typeref (identifier))))
    (declType
      (genericTpl
        (identifier)
        (kLt)
        (genericArgs
          (genericArg (identifier) (identifier) (typeref (identifier))))
        (kGt))
      (kEq)
      (type (typeref (identifier))))
    (declType
      (genericTpl
        (identifier)
        (kLt)
        (genericArgs
          (genericArg (identifier))
          (genericArg (identifier) (typeref (identifier))))
        (kGt))
      (kEq)
      (type (typeref (identifier))))
    (declType
      (genericTpl
        (identifier)
        (kLt)
        (genericArgs
          (genericArg (identifier) (identifier) (typeref (identifier)))
          (genericArg (identifier) (identifier) (typeref (identifier))))
        (kGt))
      (kEq)
      (type (typeref (identifier))))))

===
Generic Specialization
===

type
  a = b<c>;
  a = b<c,d>;
  a = b<c, d<e, f> >;

var
  a: b<c>;
  a: b<c,d>;
  a: b<c, d<e, f> >;

---

(root
  (declTypes (kType)
    (declType (identifier) (kEq)
      (type
        (typeref
          (typerefTpl
            (identifier)
            (kLt)
            (typerefArgs
              (identifier))
            (kGt)))))
    (declType (identifier) (kEq)
      (type
        (typeref
          (typerefTpl
            (identifier)
            (kLt)
            (typerefArgs
              (identifier)
              (identifier))
            (kGt)))))
    (declType (identifier) (kEq)
      (type
        (typeref
          (typerefTpl
            (identifier)
            (kLt)
            (typerefArgs
              (identifier)
              (typerefTpl
                (identifier)
                (kLt)
                (typerefArgs
                  (identifier)
                  (identifier))
                (kGt)))
            (kGt))))))
  (declVars (kVar)
    (declVar
      (identifier)
      (type
        (typeref
          (typerefTpl
            (identifier)
            (kLt)
            (typerefArgs
              (identifier))
            (kGt)))))
    (declVar
      (identifier)
      (type
        (typeref
          (typerefTpl
            (identifier)
            (kLt)
            (typerefArgs
              (identifier)
              (identifier))
            (kGt)))))
    (declVar
      (identifier)
      (type
        (typeref
          (typerefTpl
            (identifier)
            (kLt)
            (typerefArgs
              (identifier)
              (typerefTpl
                (identifier)
                (kLt)
                (typerefArgs
                  (identifier)
                  (identifier))
                (kGt)))
            (kGt)))))))


===
Generic Routines
===

procedure a<b>(c: b); forward;

procedure a<b,c>.d<e>.Main<f>;
begin
end;

---

(root
  (declProc (kProcedure)
    (genericTpl
      (identifier)
      (kLt)
      (genericArgs
        (genericArg 
          (identifier)))
      (kGt))
    (declArgs
      (declArg
        (identifier)
        (type (typeref (identifier)))))
    (kForward))
  (defProc
    (declProc (kProcedure)
      (genericDot
        (genericDot
          (genericTpl
            (identifier)
            (kLt)
            (genericArgs
              (genericArg
                (identifier)
                (identifier)))
            (kGt))
          (kDot)
          (genericTpl
            (identifier)
            (kLt)
            (genericArgs
              (genericArg
                (identifier)))
            (kGt)))
        (kDot)
        (genericTpl
          (identifier)
          (kLt)
          (genericArgs
            (genericArg
              (identifier)))
          (kGt))))
    (block
      (kBegin)
      (kEnd))))


===
Generic Expressions
===

procedure a;
begin
  if b<c>(d) < e<f,g> then
    ;
end;

---

(root
  (defProc
    (declProc (kProcedure) (identifier))
    (block
      (kBegin)
      (if
        (kIf)
        (exprBinary
          (exprCall
            (exprTpl
              (identifier)
              (kLt)
              (identifier)
              (kGt))
            (exprArgs
              (identifier)))
          (kLt)
          (exprTpl
            (identifier)
            (kLt)
            (identifier)
            (identifier)
            (kGt)))
        (kThen))
      (kEnd))))
