summary refs log tree commit diff stats
path: root/examples/talk/dsl.nim
blob: 2dde517903801a06b12947e98abacd7223a75310 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import strutils

template html(name, matter: untyped) =
  proc name(): string =
    result = "<html>"
    matter
    result.add("</html>")

template nestedTag(tag: untyped) =
  template tag(matter: typed) =
    result.add("<" & astToStr(tag) & ">")
    matter
    result.add("</" & astToStr(tag) & ">")

template simpleTag(tag: untyped) =
  template tag(matter: untyped) =
    result.add("<$1>$2</$1>" % [astToStr(tag), matter])

nestedTag body
nestedTag head
nestedTag ul
simpleTag title
simpleTag li

html mainPage:
  head:
    title "now look at this"
  body:
    ul:
      li "Nim is quite capable"

echo mainPage()
ighlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#
#
#           The Nim Compiler
#        (c) Copyright 2020 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# included from cgen.nim

## Code specialization instead of the old, incredibly slow 'genericReset'
## implementation.

proc specializeResetT(p: BProc, accessor: Rope, typ: PType)

proc specializeResetN(p: BProc, accessor: Rope, n: PNode;
                     typ: PType) =
  if n == nil: return
  case n.kind
  of nkRecList:
    for i in 0..<n.len:
      specializeResetN(p, accessor, n[i], typ)
  of nkRecCase:
    if (n[0].kind != nkSym): internalError(p.config, n.info, "specializeResetN")
    let disc = n[0].sym
    if disc.loc.r == "": fillObjectFields(p.module, typ)
    if disc.loc.t == nil:
      internalError(p.config, n.info, "specializeResetN()")
    lineF(p, cpsStmts, "switch ($1.$2) {$n", [accessor, disc.loc.r])
    for i in 1..<n.len:
      let branch = n[i]
      assert branch.kind in {nkOfBranch, nkElse}
      if branch.kind == nkOfBranch:
        genCaseRange(p, branch)
      else:
        lineF(p, cpsStmts, "default:$n", [])
      specializeResetN(p, accessor, lastSon(branch), typ)
      lineF(p, cpsStmts, "break;$n", [])
    lineF(p, cpsStmts, "} $n", [])
    specializeResetT(p, "$1.$2" % [accessor, disc.loc.r], disc.loc.t)
  of nkSym:
    let field = n.sym
    if field.typ.kind == tyVoid: return
    if field.loc.r == "": fillObjectFields(p.module, typ)
    if field.loc.t == nil:
      internalError(p.config, n.info, "specializeResetN()")
    specializeResetT(p, "$1.$2" % [accessor, field.loc.r], field.loc.t)
  else: internalError(p.config, n.info, "specializeResetN()")

proc specializeResetT(p: BProc, accessor: Rope, typ: PType) =
  if typ == nil: return

  case typ.kind
  of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred,
     tySink, tyOwned:
    specializeResetT(p, accessor, lastSon(typ))
  of tyArray:
    let arraySize = lengthOrd(p.config, typ[0])
    var i: TLoc
    getTemp(p, getSysType(p.module.g.graph, unknownLineInfo, tyInt), i)
    linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
            [i.r, arraySize])
    specializeResetT(p, ropecg(p.module, "$1[$2]", [accessor, i.r]), typ[1])
    lineF(p, cpsStmts, "}$n", [])
  of tyObject:
    for i in 0..<typ.len:
      var x = typ[i]
      if x != nil: x = x.skipTypes(skipPtrs)
      specializeResetT(p, accessor.parentObj(p.module), x)
    if typ.n != nil: specializeResetN(p, accessor, typ.n, typ)
  of tyTuple:
    let typ = getUniqueType(typ)
    for i in 0..<typ.len:
      specializeResetT(p, ropecg(p.module, "$1.Field$2", [accessor, i]), typ[i])

  of tyString, tyRef, tySequence:
    lineCg(p, cpsStmts, "#unsureAsgnRef((void**)&$1, NIM_NIL);$n", [accessor])

  of tyProc:
    if typ.callConv == ccClosure:
      lineCg(p, cpsStmts, "#unsureAsgnRef((void**)&$1.ClE_0, NIM_NIL);$n", [accessor])
      lineCg(p, cpsStmts, "$1.ClP_0 = NIM_NIL;$n", [accessor])
    else:
      lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
  of tyChar, tyBool, tyEnum, tyInt..tyUInt64:
    lineCg(p, cpsStmts, "$1 = 0;$n", [accessor])
  of tyCstring, tyPointer, tyPtr, tyVar, tyLent:
    lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [accessor])
  of tySet:
    case mapSetType(p.config, typ)
    of ctArray:
      lineCg(p, cpsStmts, "#nimZeroMem($1, sizeof($2));$n",
          [accessor, getTypeDesc(p.module, typ)])
    of ctInt8, ctInt16, ctInt32, ctInt64:
      lineCg(p, cpsStmts, "$1 = 0;$n", [accessor])
    else:
      doAssert false, "unexpected set type kind"
  of {tyNone, tyEmpty, tyNil, tyUntyped, tyTyped, tyGenericInvocation,
      tyGenericParam, tyOrdinal, tyRange, tyOpenArray, tyForward, tyVarargs,
      tyUncheckedArray, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
      tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot,
      tyAnything, tyStatic, tyFromExpr, tyConcept, tyVoid, tyIterable}:
    discard

proc specializeReset(p: BProc, a: TLoc) =
  specializeResetT(p, rdLoc(a), a.t)