M README.md => README.md +42 -12
@@ 2,22 2,52 @@
This is a work-in-progress JavaScript/Node.js implementation of [BARE](https://baremessages.org/).
-The idea so far is, that the parser and converter will run with node.js, while the resulting JavaScript classes should be usable in any JavaScript environment.
+The idea is, that the schema converter runs on node.js, while the resulting JavaScript classes should be usable
+both in the browser and in other javascript environments.
-Have a look at `examples.js` on how to create type definitions in code for now.
-
-Or peek inside the `lib-bare.js`, where all conversion classes are located.
-These are to be used directly when defining your own type.
-Whenever a type takes some sort of arguments, they are static variables right at the top,
-just make sure to set them correctly since there are, as of now, no integrity checks on them.
-
-###What is still missing
- * The schema to js translator.
+### What is still missing
* Union type, this one is difficult to translate to js, so I'm going to have to think about use cases and how to make them convenient to use
* Conversion error handling and integrity verification.
* Unit tests, these will come last.
-###A note about Number and 64 bits
+### How to use
+#### Schema converter
+The converter located at `converter/bare.js` is a runnable node.js script, which takes two arguments: `[input, [output]]`.
+If one or both are not given, it will write to `stdout`, and read from `stdin` respectively.
+For now the output is barely formatted, each type gets its own line, some whitespace is added for legibility.
+
+Something to be aware of, is that JavaScript does not like to access a class which is only instantiated later on in the source.
+Should you define a type and plan to use it in other types, make sure its definition comes before any usage,
+either in the schema, or by reordering the lines in the output. JS will complain if you do otherwise.
+
+I am thinking about trying to reorder the types in code, but circular dependencies will always need manual intervention,
+and might not work in JS either way. It would be nice to have, but is rather low priority.
+
+#### Resulting module
+The output from the converter is a file which only works in conjunction with `library/bare.mjs`.
+This file contains all the message conversion logic, whereas the conversion output contains the layout specifics
+of the types you specified in your schema file.
+
+My default these two are to be used as [ES6 Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules).
+The benefit of this is, that you do not need to have any of the hidden classes in your scope, since they are only needed
+in the type definitions of the second file. Most browsers support this spec, and so does node.js, if the files end in `.mjs`.
+
+Should your environment not support this feature, or you don't want to use modules, you can full well remove the import and export statements,
+and load the two files like regular scripts. (I'm not 100% on this, but you can probably even leave them in)
+
+##### Now to the actual how-to for using this in a web page:
+
+If you want to use a bare type in your `main.js` script file, you need to load it as a module: `<script type="module" src="main.js"></script>`.
+The basic gist is, that modules do not share a scope, but read the MDN article above for more details.
+
+Then in this file you can use an [import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)
+statement to either load all your types in an object: `import YourName from './path/to/output.js';`.
+Just make sure that the `library/bare.mjs` file is in the same folder as the output, or edit the import statement to match its location.
+
+Or you can only load some types directly into your scope: `import {Address, Point} from './path/to/output.js';`.
+You can even rename them with `Type as OtherName` inside those brackets, should that matter in your use case.
+
+### A note about Number and 64 bits
Javascript is a wonderful language, and as such it doesn't use an integer type for numbers.
Instead, every single number is stored as a double precision float.
This limits the usable range of integers to 53 bits, which means the maximum unsigned value is just over 9 quadrillion `(10^15)`.
@@ 26,5 56,5 @@ There is the [BitInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Re
But it has limitations; you can't use them in Math functions or beside regular Numbers.
Keep this in mind when using the variable length, and the 64 bit integer types, since these return a BigInt by default.
-The lib provides `safeNumber` which will convert a BigInt to Number if it fits into 53 bits, or throw an Error if it does not fit if you just need a little more headroom.
+The lib provides `safeNumber` which will convert a BigInt to Number if it fits into 53 bits, or throw an Error if it does not fit, for when you just need a little more headroom.
R bare.js => converter/bare.js +7 -6
@@ 10,6 10,10 @@
const fs = require('fs');
+const tokenizer = require('./tokenizer');
+const parser = require('./parser');
+const templates = require('./templates');
+
function readFile(fileName) {
return new Promise((resolve, reject) => {
fs.readFile(fileName, {encoding: 'utf-8'}, function(err, data) {
@@ 58,11 62,6 @@ function writeStdout(data) {
});
}
-function parseSchema(schema) {
- // TODO lexer, parser, conversion to js classes
- return schema;
-}
-
(async function() {
let [input, output] = process.argv.slice(2, 4);
let schema;
@@ 71,7 70,9 @@ function parseSchema(schema) {
} else {
schema = await readStdin();
}
- let jsModule = parseSchema(schema);
+ let tokenList = tokenizer.tokenizeSchema(schema);
+ let objectTree = parser.parseSchema(tokenList);
+ let jsModule = templates.generateClasses(objectTree);
if (output) {
await writeFile(jsModule);
} else {
A converter/parser.js => converter/parser.js +260 -0
@@ 0,0 1,260 @@
+// TODO use these for verification
+const USER_NAME_PATTERN = RegExp(/[A-Z][A-Za-z0-9]*/);
+const FIELD_NAME_PATTERN = RegExp(/[a-z][A-Za-z0-9]*/);
+const ENUM_VALUE_PATTERN = RegExp(/[A-Z][A-Z0-9]*/);
+
+class TokenError extends Error {
+ constructor(token, expected) {
+ super(`Unexpected token ${token[0]}, expected ${expected}`);
+
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, TokenError);
+ }
+ }
+}
+
+function parseSchema(tokenList) {
+ let types = [];
+ while (tokenList.length > 0) {
+ let type = parseSchema_type(tokenList);
+ types.push(type);
+ }
+ return types;
+}
+
+function parseSchema_type(tokenList) {
+ let token = tokenList.shift();
+ if (token[0] === 'TTYPE') {
+ return parseSchema_userType(tokenList);
+ } else if (token[0] === 'TENUM') {
+ return parseSchema_userEnum(tokenList);
+ } else {
+ throw new TokenError(token, "'type' or 'enum'");
+ }
+}
+
+function parseSchema_userType(tokenList) {
+ let token = tokenList.shift();
+ if (token[0] !== 'TNAME') {
+ throw new TokenError(token, 'type name');
+ }
+
+ let type = {};
+ type.name = token[1];
+ type.type = parse_type(tokenList);
+ return type;
+}
+
+function parseSchema_userEnum(tokenList) {
+ let token = tokenList.shift();
+ if (token[0] !== 'TNAME') {
+ throw new TokenError(token, 'enum name');
+ }
+
+ let enum_ = {}
+ enum_.name = token[1];
+ enum_.type = {
+ type: 'BareEnum',
+ keys: [],
+ };
+
+ token = tokenList.shift();
+ if (token[0] !== 'TLBRACE') {
+ throw new TokenError(token, '{');
+ }
+
+ let nextValue = 0;
+ for (;;) {
+ token = tokenList.shift();
+ if (token[0] === 'TRBRACE') {
+ break;
+ }
+ if (token[0] !== 'TNAME') {
+ throw new TokenError(token, 'value name');
+ }
+
+ let name = token[1];
+
+ if (tokenList[0][0] === 'TEQUAL') {
+ tokenList.shift();
+ token = tokenList.shift();
+ if (token[0] !== 'TINTEGER') {
+ throw new TokenError(token, 'integer');
+ }
+ nextValue = Number(token[1]);
+ }
+ enum_.type.keys.push([nextValue, name]);
+ nextValue++;
+ }
+ return enum_;
+}
+
+function parse_type(tokenList) {
+ let token = tokenList.shift();
+ switch (token[0]) {
+ case 'TUINT':
+ return 'BareUInt';
+ case 'TU8':
+ return 'BareU8';
+ case 'TU16':
+ return 'BareU16';
+ case 'TU32':
+ return 'BareU32';
+ case 'TU64':
+ return 'BareU64';
+ case 'TINT':
+ return 'BareInt';
+ case 'TI8':
+ return 'BareI8';
+ case 'TI16':
+ return 'BareI16';
+ case 'TI32':
+ return 'BareI32';
+ case 'TI64':
+ return 'BareI64';
+ case 'TF32':
+ return 'BareF32';
+ case 'TF64':
+ return 'BareF64';
+ case 'TBOOL':
+ return 'BareBool';
+ case 'TSTRING':
+ return 'BareString';
+ case 'TVOID':
+ return 'BareVoid';
+ case 'TOPTIONAL':
+ let optional = {};
+ optional.type = 'BareOptional';
+ token = tokenList.shift();
+ if (token[0] !== 'TLANGLE') {
+ throw new TokenError(token, '<');
+ }
+ optional.subtype = parse_type(tokenList);
+ token = tokenList.shift();
+ if (token[0] !== 'TRANGLE') {
+ throw new TokenError(token, '>');
+ }
+ return optional;
+ case 'TDATA':
+ if (tokenList[0][0] === 'TLANGLE') {
+ let data = {}
+ data.type = 'BareDataFixed';
+ tokenList.shift();
+ token = tokenList.shift();
+ if (token[0] !== 'TINTEGER') {
+ throw new TokenError(token, 'length');
+ }
+ data.len = Number(token[1]);
+ token = tokenList.shift();
+ if (token[0] !== 'TRANGLE') {
+ throw new TokenError(token, '>');
+ }
+ return data;
+ } else {
+ return 'BareData';
+ }
+ case 'TLBRACE':
+ return parse_struct(tokenList);
+ case 'TLBRACKET':
+ let array = {};
+ token = tokenList.shift();
+ if (token[0] === 'TRBRACKET') {
+ array.type = 'BareArray';
+ } else if (token[0] === 'TINTEGER') {
+ array.type = 'BareArrayFixed';
+ array.len = Number(token[1]);
+ token = tokenList.shift();
+ if (token[0] !== 'TRBRACKET') {
+ throw new TokenError(token, ']');
+ }
+ } else {
+ throw new TokenError(token, "']' or array length");
+ }
+ array.subtype = parse_type(tokenList);
+ return array;
+ case 'TMAP':
+ let map = {};
+ map.type = 'BareMap';
+ token = tokenList.shift();
+ if (token[0] !== 'TLBRACKET') {
+ throw new TokenError(token, '[');
+ }
+ map.keyType = parse_type(tokenList);
+ token = tokenList.shift();
+ if (token[0] !== 'TRBRACKET') {
+ throw new TokenError(token, ']');
+ }
+ map.valueType = parse_type(tokenList);
+ return map;
+ case 'TLPAREN':
+ let union = {};
+ union.type = 'BareUnion';
+ union.subtypes = [];
+ let index = 0;
+ for (;;) {
+ let subtype = parse_type(tokenList);
+ token = tokenList.shift();
+ if (token[0] === 'TEQUAL') {
+ token = tokenList.shift();
+ if (token[0] !== 'TINTEGER') {
+ throw new TokenError(token, 'integer');
+ }
+ index = Number(token[1]);
+ token = tokenList.shift();
+ }
+ let sub = [subtype, index];
+ union.subtypes.push(sub);
+ if (token[0] === 'TPIPE') {
+ index++;
+ } else if (token[0] === 'TRPAREN') {
+ break;
+ } else {
+ throw new TokenError(token, "'|' or ')'");
+ }
+ }
+ return union;
+ case 'TNAME':
+ return token[1];
+ default:
+ throw new TokenError(token, 'a type');
+ }
+}
+
+function parse_struct(tokenList) {
+ let struct = {};
+ struct.type = 'BareStruct';
+ struct.entries = [];
+ let token;
+ for (;;) {
+ token = tokenList.shift();
+ if (token[0] === 'TRBRACE') {
+ return struct;
+ }
+ if (token[0] !== 'TNAME') {
+ throw new TokenError(token, 'field name');
+ }
+ let name = token[1];
+ let type;
+
+ token = tokenList.shift();
+ if (token[0] !== 'TCOLON') {
+ throw new TokenError(token, ':');
+ }
+
+ if (tokenList[0][0] === 'TNAME') {
+ token = tokenList.shift();
+ type = token[1];
+ } else {
+ type = parse_type(tokenList);
+ }
+ struct.entries.push([name, type]);
+
+ if (tokenList[0][0] === 'TCOMMA') {
+ tokenList.shift(); // consume optional comma
+ }
+ }
+}
+
+module.exports = {
+ parseSchema: parseSchema,
+};<
\ No newline at end of file
A converter/templates.js => converter/templates.js +133 -0
@@ 0,0 1,133 @@
+const import_statement = "import {mapEnum,mapUnion,safeNumber,BareUInt,BareInt," +
+ "BareU8,BareU16,BareU32,BareU64,BareI8,BareI16,BareI32,BareI64,BareF32,BareF64," +
+ "BareBool,BareEnum,BareString,BareDataFixed,BareData,BareVoid,BareOptional," +
+ "BareArrayFixed,BareArray,BareMap,BareUnion,BareStruct} from './bare.mjs';";
+
+const named_class = (name, type, content) => `class ${name} extends ${type} \{ ${content} \}`;
+
+const inline_class = (type, content) => `class extends ${type} \{ ${content} \}`;
+
+const enum_content = (pairs) => `static keys = mapEnum(this, \{ ${pairs.map(p => `${p[0]}: '${p[1]}'`).join(', ')} \});`;
+
+const fixed_content = (len) => `static length = ${len};`;
+const typed_content = (type) => `static type = ${type};`;
+
+const data_fixed_content = (len) => fixed_content(len);
+
+const optional_content = (type) => typed_content(type);
+
+const array_fixed_content = (len, type) => `${fixed_content(len)} ${typed_content(type)}`;
+const array_content = (type) => typed_content(type);
+
+const map_content = (keyType, valueType) => `static keyType = ${keyType}; static valueType = ${valueType};`;
+
+const union_content = (types) => ""; // TODO
+
+const struct_content = (entries) => `static entries = [ ${entries.map(e => `['${e[0]}', ${e[1]}]`).join(', ')} ];`;
+
+const export_statement = (typeNames) => `export \{ ${typeNames.join(', ')} \};`;
+const export_default_statement = (typeNames) => `export default \{ ${typeNames.map(t => `${t}: ${t}`).join(', ')} \};`;
+
+function resolveContent(objectTail) {
+ if (typeof objectTail === 'string' || objectTail instanceof String) {
+ return objectTail;
+ }
+ let type = objectTail.type;
+ let typeContent;
+ let content;
+ switch (type) {
+ case 'BareEnum':
+ content = enum_content(objectTail.keys);
+ break;
+ case 'BareDataFixed':
+ content = data_fixed_content(objectTail.len);
+ break;
+ case 'BareOptional':
+ if (typeof objectTail.subtype === 'string') {
+ typeContent = objectTail.subtype;
+ } else {
+ typeContent = inline_class(objectTail.subtype.type, resolveContent(objectTail.subtype));
+ }
+ content = optional_content(typeContent);
+ break;
+ case 'BareArrayFixed':
+ if (typeof objectTail.subtype === 'string') {
+ typeContent = objectTail.subtype;
+ } else {
+ typeContent = inline_class(objectTail.subtype.type, resolveContent(objectTail.subtype));
+ }
+ content = array_fixed_content(objectTail.len, typeContent);
+ break;
+ case 'BareArray':
+ if (typeof objectTail.subtype === 'string') {
+ typeContent = objectTail.subtype;
+ } else {
+ typeContent = inline_class(objectTail.subtype.type, resolveContent(objectTail.subtype));
+ }
+ content = array_content(typeContent);
+ break;
+ case 'BareMap':
+ let keyContent, valueContent;
+ if (typeof objectTail.keyType === 'string') {
+ keyContent = objectTail.keyType;
+ } else {
+ keyContent = inline_class(objectTail.keyType.type, resolveContent(objectTail.keyType));
+ }
+ if (typeof objectTail.valueType === 'string') {
+ valueContent = objectTail.valueType;
+ } else {
+ valueContent = inline_class(objectTail.valueType.type, resolveContent(objectTail.valueType));
+ }
+ content = map_content(keyContent, valueContent);
+ break;
+ case 'BareUnion':
+ content = union_content(objectTail.subtypes); // TODO
+ break;
+ case 'BareStruct':
+ let entryContent = [];
+ for (let j = 0; j < objectTail.entries.length; j++) {
+ let [name, subtype] = objectTail.entries[j];
+ let subtypeContent = resolveContent(subtype);
+ if (typeof subtype === 'string') {
+ subtypeContent = subtype;
+ } else {
+ subtypeContent = inline_class(subtype.type, resolveContent(subtype));
+ }
+ entryContent.push([name, subtypeContent]);
+ }
+ content = struct_content(entryContent);
+ break;
+ default:
+ throw Error("Unknown content type '" + type + "'");
+ }
+ return content;
+}
+
+function generateClasses(objectTree) {
+ let output = import_statement;
+ let typeNames = [];
+
+ for (let i = 0; i < objectTree.length; i++) {
+ let object = objectTree[i];
+ let type, content = '';
+ if (typeof object.type === 'string') {
+ type = object.type;
+ } else {
+ type = object.type.type;
+ content = resolveContent(object.type);
+ }
+ typeNames.push(object.name);
+ output += '\n';
+ output += named_class(object.name, type, content);
+ }
+ output += '\n';
+ output += export_statement(typeNames);
+ output += '\n';
+ output += export_default_statement(typeNames);
+
+ return output;
+}
+
+module.exports = {
+ generateClasses: generateClasses,
+};<
\ No newline at end of file
A converter/tokenizer.js => converter/tokenizer.js +124 -0
@@ 0,0 1,124 @@
+const NUMERIC_PATTERN = RegExp(/^[0-9]+/);
+const LETTER_PATTERN = RegExp(/^[a-zA-Z]+/);
+const WORD_PATTERN = RegExp(/^[a-zA-Z0-9_]+/);
+
+function tokenizeSchema(schema) {
+ let tokenList = [];
+ let lines = schema.split('\n');
+ for (let i = 0; i < lines.length; i++) {
+ // clean up whitespace
+ let line = lines[i].trim().replace(/\s+/g, ' ');
+ for (let j = 0; j < line.length;) {
+ let c = line.charAt(j);
+ if (c === ' ') {
+ // skip character
+ j++;
+ } else if (c === '#') {
+ // skip line
+ break;
+ } else if (LETTER_PATTERN.test(c)) {
+ let match = line.slice(j).match(WORD_PATTERN);
+ if (!match) {
+ throw SyntaxError(`Could not match word token (@${j}):\n\t${line}`);
+ }
+ let token = stringToToken(match[0]);
+ tokenList.push(token);
+ j += match[0].length;
+ } else if (NUMERIC_PATTERN.test(c)) {
+ let match = line.slice(j).match(NUMERIC_PATTERN);
+ if (!match) {
+ throw SyntaxError(`Could not match digit token (@${j}):\n\t${line}`);
+ }
+ tokenList.push(['TINTEGER', match[0]]);
+ j += match[0].length;
+ } else {
+ let token = charToToken(c);
+ tokenList.push(token);
+ j++;
+ }
+ }
+ }
+ return tokenList;
+}
+
+function stringToToken(string) {
+ switch (string) {
+ case 'type':
+ return ['TTYPE', ''];
+ case 'enum':
+ return ['TENUM', ''];
+ case 'uint':
+ return ['TUINT', ''];
+ case 'u8':
+ return ['TU8', ''];
+ case 'u16':
+ return ['TU16', ''];
+ case 'u32':
+ return ['TU32', ''];
+ case 'u64':
+ return ['TU64', ''];
+ case 'int':
+ return ['TINT', ''];
+ case 'i8':
+ return ['TI8', ''];
+ case 'i16':
+ return ['TI16', ''];
+ case 'i32':
+ return ['TI32', ''];
+ case 'i64':
+ return ['TI64', ''];
+ case 'f32':
+ return ['TF32', ''];
+ case 'f64':
+ return ['TF64', ''];
+ case 'bool':
+ return ['TBOOL', ''];
+ case 'string':
+ return ['TSTRING', ''];
+ case 'data':
+ return ['TDATA', ''];
+ case 'void':
+ return ['TVOID', ''];
+ case 'optional':
+ return ['TOPTIONAL', ''];
+ case 'map':
+ return ['TMAP', ''];
+ default:
+ return ['TNAME', string];
+ }
+}
+
+function charToToken(c) {
+ switch (c) {
+ case '<':
+ return ['TLANGLE', ''];
+ case '>':
+ return ['TRANGLE', ''];
+ case '{':
+ return ['TLBRACE', ''];
+ case '}':
+ return ['TRBRACE', ''];
+ case '[':
+ return ['TLBRACKET', ''];
+ case ']':
+ return ['TRBRACKET', ''];
+ case '(':
+ return ['TLPAREN', ''];
+ case ')':
+ return ['TRPAREN', ''];
+ case ',':
+ return ['TCOMMA', ''];
+ case '|':
+ return ['TPIPE', ''];
+ case '=':
+ return ['TEQUAL', ''];
+ case ':':
+ return ['TCOLON', ''];
+ default:
+ throw SyntaxError(`Unknown character '${c}'`);
+ }
+}
+
+module.exports = {
+ tokenizeSchema: tokenizeSchema,
+};<
\ No newline at end of file
R lib-bare.js => library/bare.mjs +33 -29
@@ 9,26 9,6 @@ function joinUint8Arrays(a, b) {
return c;
}
-function twoWayMap(pairs) {
- let map = {};
- for (let i = 0; i < pairs.length; i++) {
- let [a, b] = pairs[i];
- map[a] = b;
- map[b] = a;
- }
- return map;
-}
-
-function reverseMapping(obj) {
- let entries = Object.entries(obj);
- let reverse = {};
- for (let i = 0; i < entries.length; i++) {
- let [key, val] = entries[i];
- reverse[val] = key;
- }
- return reverse;
-}
-
function safeNumber(bigInt) {
if (bigInt > MAX_U53 || bigInt < -MAX_U53) {
throw RangeError("BigInt value out of double precision range (53 bits)");
@@ 506,13 486,20 @@ class BareMap extends BareType {
}
}
-// TODO how do I store/represent the BARE type of an object for unions???
+function mapUnion(obj) {
+ let entries = Object.entries(obj);
+ let reverse = {};
+ for (let i = 0; i < entries.length; i++) {
+ let [key, val] = entries[i];
+ reverse[val] = key;
+ }
+ return reverse;
+}
+// TODO how do I store/represent the BARE type of an object for unions??? also; use BigInt
class BareUnion extends BareType {
// INVARIANT: has at least one type
static types; // = twoWayMap([[class, i], ...])
- // TODO use BigInt
-
static pack(obj) {
let unionIndex = this.types[obj.constructor];
if (!unionIndex) {
@@ 564,10 551,27 @@ class BareStruct extends BareType {
}
}
-module.exports = {
- twoWayMap: twoWayMap,
- reverseMapping: reverseMapping,
+export {
+ mapEnum, mapUnion, safeNumber,
+ BareUInt, BareInt,
+ BareU8, BareU16, BareU32, BareU64,
+ BareI8, BareI16, BareI32, BareI64,
+ BareF32, BareF64,
+ BareBool,
+ BareEnum,
+ BareString,
+ BareDataFixed, BareData,
+ BareVoid,
+ BareOptional,
+ BareArrayFixed, BareArray,
+ BareMap,
+ BareUnion,
+ BareStruct,
+};
+
+export default {
mapEnum: mapEnum,
+ mapUnion: mapUnion,
safeNumber: safeNumber,
UInt: BareUInt,
Int: BareInt,
@@ 582,7 586,7 @@ module.exports = {
F32: BareF32,
F64: BareF64,
Bool: BareBool,
- Enum: BareEnum, // TODO
+ Enum: BareEnum,
String: BareString,
DataFixed: BareDataFixed,
Data: BareData,
@@ 591,6 595,6 @@ module.exports = {
ArrayFixed: BareArrayFixed,
Array: BareArray,
Map: BareMap,
- Union: BareUnion, // TODO
+ Union: BareUnion,
Struct: BareStruct,
-}
+};<
\ No newline at end of file
R example.js => library/example.mjs +23 -23
@@ 1,19 1,19 @@
-let BARE = require("./lib-bare");
+import Bare from './bare.mjs';
-class Point extends BARE.ArrayFixed {
+class Point extends Bare.ArrayFixed {
static length = 3;
- static type = BARE.F32;
+ static type = Bare.F32;
}
-class Test1 extends BARE.Struct {
+class Test1 extends Bare.Struct {
static entries = [
- ['str', BARE.String],
+ ['str', Bare.String],
['pos', Point],
- ['verts', class extends BARE.Array {
+ ['verts', class extends Bare.Array {
static type = Point;
}],
- ['test', BARE.F64],
- ['flag', BARE.Bool],
+ ['test', Bare.F64],
+ ['flag', Bare.Bool],
];
}
@@ 28,12 28,12 @@ let test1 = {
flag: false,
};
-class Test2 extends BARE.Struct {
+class Test2 extends Bare.Struct {
static entries = [
- ['vals', class extends BARE.Array {
- static type = BARE.Int;
+ ['vals', class extends Bare.Array {
+ static type = Bare.Int;
}],
- ['uint', BARE.UInt],
+ ['uint', Bare.UInt],
];
}
@@ 42,8 42,8 @@ let test2 = {
'uint': 365555,
};
-class ChannelEnum extends BARE.Enum {
- static keys = BARE.mapEnum(this, {
+class ChannelEnum extends Bare.Enum {
+ static keys = Bare.mapEnum(this, {
0: 'RED',
1: 'BLUE',
2: 'GREEN',
@@ 51,14 51,14 @@ class ChannelEnum extends BARE.Enum {
});
}
-class Pair extends BARE.Struct {
+class Pair extends Bare.Struct {
static entries = [
['channel', ChannelEnum],
- ['value', BARE.F64],
+ ['value', Bare.F64],
];
}
-class Test3 extends BARE.ArrayFixed {
+class Test3 extends Bare.ArrayFixed {
static length = 2;
static type = Pair;
}
@@ 74,15 74,15 @@ let test3 = [
},
];
-class Address extends BARE.Struct {
+class Address extends Bare.Struct {
static entries = [
- ['address', class extends BARE.ArrayFixed {
+ ['address', class extends Bare.ArrayFixed {
static length = 4;
- static type = BARE.String;
+ static type = Bare.String;
}],
- ['city', BARE.String],
- ['state', BARE.String],
- ['country', BARE.String],
+ ['city', Bare.String],
+ ['state', Bare.String],
+ ['country', Bare.String],
];
}