Skip to content

Description of the syntax and semantics of shiftless

Notifications You must be signed in to change notification settings

shiftless-config/standard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 

Repository files navigation

shiftless Configuration and Data Serialization Format

Syntax

Atom

These are the smallest unit of data. An atom can be a string of characters, a number, or a symbol. Although there are different types of atoms. The shiftless library should provide a way for the user to get the original string that the user typed in for each one (excluding the single quotes for strings).

Number

regex: -?[0-9]+

examples:

  • -1
  • 019823704
  • 67813645098123948

Floating Point Number

regex: -?[0-9]+[.][0-9]+ (must have a number in front of decimal).

examples:

  • 0.0
  • 1.0
  • -0.1093847

String

Strings are any sequence of characters surrounded in single quotes. Single quotes inside can be escaped with a single back slash and thus a backslash is a double back slash.

examples:

Symbol

regex: [^ \r\t\n]+ and must contain at least one non-number and should not contain ', [, or ] either. It is suggested to use hyphens to separate multiple words. Symbols are also case insensitive.

examples:

  • io-mode
  • https://example.com
  • section-title

S-expressions

All atoms are also s-expressions. S-expressions can also be a sequence of s-expressions separated by white space and surrounded by square brackets.

examples:

[1 2 3]
[I 'am' [sexp 2] !]
[]

As you can see, the s-expressions can be nested.

Comments

It can be useful to leave comments in configuration that are for only humans to read. This can be done with ; which will start a comment and go to the end of the line.

example:

These symbol are part of configuration.
so are these ;; these ones are just comments and are not symbol at all

Semantics

In this section, There are Javascript equivalents of each of the shiftless configuration data structures. This is just one possible way to convert them to help you understand the semantics. The shiftless library should actually have an interface that allows the programmer to get whatever type is needed for the program (example: the string '5.30' instead of the floating point number 5.3).

Sequence

This is equivalent to a linked list or array in your programming language. Any s-expression list that is not an association is a sequence. Empty sequences can be written as [] or the special symbol nil.

examples:

[/bin/bash my-script.sh https://example.com 54]
['=' east west]

gets converted into Javascript like so:

["/bin/bash", "my-script.sh", "https://example.com", 54]
["=", "east", "west"]

Association

This is equivalent to an object, hash-table, dictionary, associative array, or associative list. It is an s-expressions list of triplets: key = value. The = must be symbols. If a sequence contains non-string = and is not a valid association, it is an error and is not valid shiftless. key can be either a symbol or a sequence of symbols representing nested singleton keys. value can be any s-expression except they symbol =. Duplicate keys are an error, unless the keys are referred to using the list notation, then only bottom level duplicates are error. The empty association can be written as [] or the special symbol nil.

examples:

[key = value
 [key2 key] = [1 2 3]]

and in Javascript:

{
  "key": "value",
  "key2": {
      "key": [1, 2, 3]
  }
}

duplicate examples:

;; error
[key = value
 key = 1]
;; no error
[[key key1] = value1
 [key key2] = value2]

Javascript:

{
  "key": {
    "key1": "value1",
    "key2": "value2"
  }
}

Boolean

The special symbol t should be interpreted as Boolean true. The special symbol nil, the empty sequence, the empty association, and any absent property are all Boolean false. Consequently, they are all printed the same way: nil.

It is important to consider absent properties being false when creating a configuration schema: If you are creating a configuration for a robot, it is preferred to have a kill-humans option (that defaults to false), than a dont-kill-humans option. Along this same line, the shiftless library should provide a function to tell if a configuration property is present or not by using the string value: "[]" or "nil" for explicitly false, and "" for absent and implicitly false. This way, we can provide a default true for absent properties. The [] should be parsed as the symbol nil so it should retain its original string form like all atoms.

The caveat of the approach is that the shiftless library must provide some interface to retrieve non-existent configuration values to avoid null related errors.

examples:

[key = t
 [key2 key] = []]
let config = {
    "key": true,
    "key2": {
        "key": false
    }
};
config["key2"]["key"] // false
config["key2"]["key2"] // undefined which is falsy
config["key2"]["key2"]["key"] // error. Don't let this happen! Define an interface instead.
// example interface
access(config, "key2", "key2", "key") // false

Top Level

In shiftless the top level is always going to start with [ and end with ], thus they are implied!

example:

key = t
[key2 key] = nil

is exactly the same as the previous example. This indeed means that a totally empty configuration is just Boolean false.

Referring to Previously Defined Properties

It is sometime useful to make one property depend on another. For this situation, there is a special kind of s-expression which starts with .[ and ends with ]; That is, it is a regular s-expression with a period directly in front of it. This s-expression must be a non-nested sequence of symbols (or positive integers representing an index in a sequence starting at 0). which refer to a previously defined property. This sequence must start at the top level. They can appear almost anywhere.

example:

server = [
  hostname = localhost
  port = 8080]

pages = [
  home-page = http://.[server hostname]:.[server port] ; http://localhost:8080
  login = '.[pages home-page]/login']                  ; http://localhost:8080/login

strange-number = 192.[server port].182 ; 1928080.182

Of course by the time it gets to a usable state in your programming language (past the shiftless library), home-page and login will both be strings. strange-number will be a floating point number though. Be careful about referring to non-existent properties, because they will become nil.

There is no way to include properties from another file; however, beyond the scope of a shiftless library, one could define meaning to arbitrary symbols such as include.

example:

[include file1.shl file2.shl]

Because this happens beyond the shiftless library, one could define their own semantics for overwriting properties from other files as well.

Indentation

Indentation doesn’t really matter, but it is nice to have some consistency. If there is a line break in an s-expression list the next element should line up with the start of the first element of the s-expression.

example:

[1 3 4
 2 54
 2]

The exception is when the line break is right after the opening square bracket. Then the indentation should be <current-indentation> + <indentation (default 2)>.

examples:

[
  1 3 4
  2 54
  2]

[key = [
  key = value
  key2 = [
    2 3 4]]]

File extensions

shiftless configuration file names should end in .slc.

About

Description of the syntax and semantics of shiftless

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published