|
| 1 | +# Convex Reader |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +Convex presents users with a rich variety of decentralised data structures. |
| 6 | + |
| 7 | +There is a common requirement for such data structures to be presented in text format. The Reader is a software component |
| 8 | + |
| 9 | +The Convex reader format is defined in an [ANTLR grammar](https://github.com/Convex-Dev/convex/blob/develop/convex-core/src/main/antlr4/convex/core/lang/reader/antlr/Convex.g4) |
| 10 | + |
| 11 | +## Format |
| 12 | + |
| 13 | +### Basic Literals |
| 14 | + |
| 15 | +Most basic values are available as literals in the reader. |
| 16 | + |
| 17 | +```clojure |
| 18 | +;; Integers - can be big integers |
| 19 | +1 |
| 20 | +456576575675675676586787888 |
| 21 | + |
| 22 | +;; Doubles |
| 23 | +1.0 |
| 24 | +-1e89 |
| 25 | +##Inf ; Positive Infinity |
| 26 | +##NaN ; Not-a-number |
| 27 | + |
| 28 | +;; Strings |
| 29 | +"Hello World" |
| 30 | +"My name is \"Shady"\" ; escaping works like Java |
| 31 | + |
| 32 | +;; Booleans |
| 33 | +true |
| 34 | +false |
| 35 | + |
| 36 | +;; Nil value |
| 37 | +nil |
| 38 | +``` |
| 39 | + |
| 40 | +### Data structures |
| 41 | + |
| 42 | +```clojure |
| 43 | +;; Vectors |
| 44 | +[1 2 3] |
| 45 | + |
| 46 | +;; Lists |
| 47 | +(+ 2 3 4) |
| 48 | + |
| 49 | +;; Sets |
| 50 | +#{:foo :bar} |
| 51 | + |
| 52 | +;; Maps |
| 53 | +{:a 1, :b 2} |
| 54 | + |
| 55 | +``` |
| 56 | + |
| 57 | +### Symbols |
| 58 | + |
| 59 | +Symbols consist of alphanumeric characters plus any of: `.*+!-_?$%&=<>:#` |
| 60 | + |
| 61 | +Examples: |
| 62 | + |
| 63 | +``` |
| 64 | +foo |
| 65 | +this-is-a-descriptive-name |
| 66 | +mysym1456757 |
| 67 | +*hello* |
| 68 | ++++<>+++ |
| 69 | +``` |
| 70 | + |
| 71 | +Symbols cannot start with a number, `:` or `#` (since these map to other readable types). These characters are valid anywhere else in the symbol however. |
| 72 | + |
| 73 | +Symbols MUST be 1-128 UTF-8 characters in length. This restriction has two purposes: |
| 74 | +- It ensure that symbols are *always* embedded values |
| 75 | +- It discourages excessive name lengths: symbols are intended for human readability! |
| 76 | + |
| 77 | +### Keywords |
| 78 | + |
| 79 | +Keywords start with `:` and are followed by a symbolic name with the same rules as a Symbol. |
| 80 | + |
| 81 | +Examples: |
| 82 | + |
| 83 | +``` |
| 84 | +:foo |
| 85 | +:name |
| 86 | +:special-key |
| 87 | +``` |
| 88 | + |
| 89 | +### Whitespace |
| 90 | + |
| 91 | +Whitespace is any combination of space, tab, comma and newline characters. |
| 92 | + |
| 93 | +Line comments are also considered whitespace. A line comment is the semicolon `;` to the end of the line |
| 94 | + |
| 95 | +```clojure |
| 96 | +;;;; This is a line comment |
| 97 | + |
| 98 | +[some symbols] ; This is also a comment that will be treated as whitespace |
| 99 | + |
| 100 | +Whitespace MAY be omitted in cases where there is no ambiguity, e.g.: |
| 101 | + |
| 102 | +```clojure |
| 103 | +(+(+ 2 3)(+ 4 5)) |
| 104 | +``` |
| 105 | + |
| 106 | +### Syntax Objects |
| 107 | + |
| 108 | +A syntax object is a value with attached metadata. Conceptually, syntax objects can be considered as wrapped values with a metadata map. |
| 109 | + |
| 110 | +Syntax objects can be specified in the Reader with the `^` symbol preceding some metadata value and the value to wrap. The exact handling of the metadata depends on its type: |
| 111 | + |
| 112 | +```clojure |
| 113 | +;; A Syntax object with the value [1 2 3] and the metadata {:foo bar} |
| 114 | +^{:foo bar} [1 2 3] |
| 115 | + |
| 116 | +;; Special handling for Symbol - adds the metadata {:tag SomeSymbol} |
| 117 | +^SomeSymbol 127 |
| 118 | + |
| 119 | +;; Special handling for Keyword - adds the metadata {:test true} |
| 120 | +^:test (fn [] (test-name)) |
| 121 | +``` |
| 122 | + |
| 123 | +Note: The Convex Lisp compiler generally compiles syntax objects to and expression that returns the value, rather than the syntax object itself. So you may need to quote a syntax object if you wish to obtain one in CVM code: |
| 124 | + |
| 125 | +```clojure |
| 126 | +^:foo [1 2 3] |
| 127 | +=> [1 2 3] |
| 128 | + |
| 129 | +(quote ^:foo [1 2 3]) |
| 130 | +=> ^{:foo true} [1 2 3] |
| 131 | + |
| 132 | +;; This also works, but may be confusing. |
| 133 | +'^{:foo true} [1 2 3] |
| 134 | +=> ^{:foo true} [1 2 3] |
| 135 | +``` |
| 136 | + |
| 137 | + |
| 138 | +## Usage |
| 139 | + |
| 140 | +### Java API |
| 141 | + |
| 142 | +Most functions of the reader are available through the static `convex.core.lang.Reader` class in the `convex-core` module. The reader takes arbitrary character strings and returns an appropriate Convex data value. |
| 143 | + |
| 144 | +Example usage: |
| 145 | + |
| 146 | +```java |
| 147 | +import convex.core.lang.Reader |
| 148 | + |
| 149 | +AVector<ACell> myVector = Reader.read("[1 2 3]"); |
| 150 | +AInteger myVector = Reader.read("546456456"); |
| 151 | +``` |
| 152 | + |
| 153 | + |
| 154 | + |
| 155 | +## Conventions |
| 156 | + |
| 157 | +### `.cvx` File Extensions |
| 158 | + |
| 159 | +Files intended to be read by the reader conventionally utilise a `.cvx` extension. |
| 160 | + |
| 161 | +Applications SHOULD name readable files with the `.cvx` extension. |
| 162 | + |
| 163 | + |
| 164 | +### Mime Types |
| 165 | + |
| 166 | +The mime type used for Convex reader compatible files is `application/cvx` |
| 167 | + |
| 168 | +Applications SHOULD return `application/cvx` as the `Content-Type` header in response to HTTP requests that return `.cvx` readable text files. |
0 commit comments