elcritch / ants

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ant

Ant provides a statically checked configuration syntax similar to YAML. However, all types are Nim objects and constructs. Here's a short example:

import ants/configure, cimport_options

antExport ImporterConfig:
  cimports:list:
    - ImportConfig:
      name: "rcutils"
      sources: "deps/rcutils/include"
      globs: ["**/*.h"]
      skipFiles:list:
        "rcutils/stdatomic_helper/win32/stdatomic.h"
        "rcutils/stdatomic_helper/gcc/stdatomic.h"
        "rcutils/stdatomic_helper.h"
      includes:list:
        "deps/rcutils/include"

      renameFiles:list:
        Replace(pattern: peg"^'string.' .+", repl: "rstring$1")
      sourceMods:list:
        - CSrcMods:
          fileMatch: peg"'rcutils/visibility_control.h'"
          deletes:list:
            LineDelete(match: peg"'RCUTILS_PUBLIC'")

This can be executed by the ants cli tool to print out a JSON or MsgPack form of the config. YAML could be added easily.

There's also an option to use ants as a library form that will recreate the Nim object's diretly. Also a helper template exists to embed the Nim interpreter directly into you another app.

ants -f tests/cimport_example.ants > output.json
ants -b -f tests/cimport_example.ants > output.mpack 
nim c -r tests/cimport_example.ants > output.json 

Note that the extension can be either ants, nim, or nims. Though nims doesn't work as well with autocomplete. The ants can be used in VSCode if you set the "file association" for it to Nim.

How does this work?

This is nice and all, but doesn't it require a complicated macro with complicated rules and broken auto-complete?

Nope! There are only a few basic constructs which are used to provide a nice syntax:

The list macro that turns any lines passed to it into an array. This can be used with openArray's to add to sequences.

var x: array[2, int]
x = list:
  1
  2

assert x == [1,2]

The - or item templates takes an object type and makes setters for each field. The setters can be used in a do block passed after the type. The setters are normal Nim proc's and can be called in any way Nim supports, including using : block calls. Note that by defining setter functions autocomplete can help find options.

Here's an example:

type Foo = object
  field1: int
  field2: string
  field3: seq[string]

var foo: Foo
foo = - Foo:
  field1(1)
  field2: "test"
  field3 ["hello", "world"]

assert foo == Foo(field1: 1, field2: @["hello", "world"])

Combining these you get a YAML! See:

var fooBars: array[2, Foo]
fooBars =
  list:
  - Foo:
    field1: 23
  - Foo:
    field1: 34
    field2: "test"
    field3:list:
      "hello"
      "world"

Exporting Data

The antExport macro is used to setup a variable for the embedded Nim interpreter to find the data.

The data is exported using a fork of msgpack4nim that can run in a Nim script. You can override the serialization by implementing pack for a given type, though this shouldn't be needed.

Credits

Thanks for @beef331 for the handy Nimscripter library!

About


Languages

Language:Nim 99.0%Language:Python 1.0%