bare-rb 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c2f2e430da54e36517c4dafc490d8f7f74253da5ab94a51082c756ab839102d
4
- data.tar.gz: 779417f3deccacd44d02d34725e77f257fad56d07f7d9fca7440faf9cd110138
3
+ metadata.gz: bdfcd51a2a757a2cb2c532d1281afe227150518a6feb625466a5f25fac16b84b
4
+ data.tar.gz: ca3ed0f25556c996c62ff70a31ef3c50d9a3e6cad0d712eb8e428013a5af0af3
5
5
  SHA512:
6
- metadata.gz: 907dca97695a2b46770e931a07e3ed42ee87a7f502867bd73cac1402e259656790973f38b2a1880fd12e62ab612524e1e676364366cfe8508b0e64c484fd6b42
7
- data.tar.gz: 485ec72d165baca3e683959336cc8b966b92eb378e7826a450b576ca56ad3b38e50950d77e2d64c15f7e983175bc3c2d5a6fbb4b11028f93ae04c173100decb4
6
+ metadata.gz: 222f83030bee145a42b3ae2ef890316f4969502f3a8e9704e3b84ffadaab0866d71163bf97b0d3f90ec02a065336343b20149375b9e628c646d8b342d0e5b27d
7
+ data.tar.gz: e757dbf048dd0f65392561a9034b3407d2fe9e2e942bcf181b3c7a25847a03e9eb515b66ef74b23115b37a94751daeae04eb4190b218a0c2dcbe2ab988ca3256
@@ -1,7 +1,17 @@
1
1
  require 'set'
2
2
  require_relative "types"
3
+ require_relative "lexer"
4
+ require_relative "parser"
3
5
 
4
6
  class Bare
7
+
8
+ def self.parse_schema(path)
9
+ # Hash of class names to BARE ASTs
10
+ # Eg. types['Customer'] == Bare.i32
11
+ types = parser(lexer(path))
12
+ return types
13
+ end
14
+
5
15
  def self.encode(msg, schema)
6
16
  return schema.encode(msg)
7
17
  end
@@ -1,9 +1,16 @@
1
+
1
2
  class BareException < StandardError
2
3
  def initialize(msg=nil)
3
4
  super
4
5
  end
5
6
  end
6
7
 
8
+ class SchemaParsingException < BareException
9
+ def initialize(msg=nil)
10
+ super
11
+ end
12
+ end
13
+
7
14
  class VoidUsedOutsideTaggedSet < BareException
8
15
  def initialize(msg = "Any type which is ultimately a void type (either directly or through user-defined types) may not be used as an optional type, struct member, array member, or map key or value. Void types may only be used as members of the set of types in a tagged union.")
9
16
  super
@@ -0,0 +1,62 @@
1
+ require_relative './exceptions'
2
+
3
+ def lexer(path)
4
+ tokens = []
5
+ line_num = 0
6
+ File.open(path).each do |line|
7
+ while line.size > 0
8
+ if /^#/.match(line)
9
+ break
10
+ elsif /^\n/.match(line)
11
+ break
12
+ elsif /^ /.match(line)
13
+ line = line[1..]
14
+ elsif /^</.match(line)
15
+ line = line[1..]
16
+ tokens << :less_than
17
+ elsif /^>/.match(line)
18
+ line = line[1..]
19
+ tokens << :greater_than
20
+ next
21
+ elsif /^{/.match(line)
22
+ line = line[1..]
23
+ tokens << :open_block
24
+ elsif /^=/.match(line)
25
+ line = line[1..]
26
+ tokens << :equal
27
+ elsif /^}/.match(line)
28
+ line = line[1..]
29
+ tokens << :close_block
30
+ elsif /^\[/.match(line)
31
+ line = line[1..]
32
+ tokens << :open_brace
33
+ elsif /^\]/.match(line)
34
+ line = line[1..]
35
+ tokens << :close_brace
36
+ elsif /^\(/.match(line)
37
+ line = line[1..]
38
+ tokens << :open_paren
39
+ elsif /^\)/.match(line)
40
+ line = line[1..]
41
+ tokens << :close_paren
42
+ elsif /^\|/.match(line)
43
+ line = line[1..]
44
+ tokens << :bar
45
+ elsif match = /^([0-9]+)/.match(line)
46
+ tokens << match[0].to_i
47
+ line = line[(match.size + 1)..]
48
+ next
49
+ elsif match = /^[a-z,A-Z,_][_,a-z,A-Z,0-9]+/.match(line)
50
+ tokens << match[0]
51
+ line = line[(match[0].size)..]
52
+ elsif /:/.match(line)
53
+ tokens << :colon
54
+ line = line[1..]
55
+ else
56
+ raise SchemaParsingException.new("Unable to lex line #{line_num} near #{line.inspect}")
57
+ end
58
+ end
59
+ line_num += 1
60
+ end
61
+ return tokens
62
+ end
@@ -0,0 +1,102 @@
1
+ require_relative './exceptions'
2
+
3
+
4
+ # enum, struct, array, fixedlenarray, data<length>
5
+ class Parser
6
+
7
+ def initialize
8
+ @definitions = {}
9
+ @primitives = {
10
+ "uint" => Bare.Uint,
11
+ "int" => Bare.Int,
12
+ "u8" => Bare.U8,
13
+ "u16" => Bare.U16,
14
+ "u32" => Bare.U32,
15
+ "u64" => Bare.U64,
16
+ "i8" => Bare.I8,
17
+ "i16" => Bare.I16,
18
+ "i32" => Bare.I32,
19
+ "i64" => Bare.I64,
20
+ "f32" => Bare.F32,
21
+ "f64" => Bare.F64,
22
+ "bool" => Bare.Bool,
23
+ "string" => Bare.String,
24
+ "data" => Bare.Data,
25
+ "void" => Bare.Void,
26
+ }
27
+ end
28
+
29
+ def definitions
30
+ @definitions
31
+ end
32
+
33
+ def parse_enum(tokens)
34
+ enum_hash = {} # {1 => "abc", 5 => :cow, 16382 => 123}
35
+ count = 0
36
+ while tokens[0] != :close_block
37
+ if tokens[1] == :equal
38
+ name = tokens[0]
39
+ int_repr = tokens[2]
40
+ enum_hash[int_repr] = name
41
+ tokens = tokens[3..]
42
+ else
43
+ enum_hash[count] = tokens[0]
44
+ count += 1
45
+ tokens = tokens[1..]
46
+ end
47
+ end
48
+ enum = Bare.Enum(enum_hash)
49
+ return tokens[1..], enum
50
+ end
51
+
52
+ def parse_struct(tokens)
53
+ struct_fields = {}
54
+ while tokens.size >= 2 and tokens[1] == :colon
55
+ name = tokens[0]
56
+ tokens, type = self.parse(tokens[2..])
57
+ struct_fields[name.to_sym] = type
58
+ end
59
+ return tokens[1..], struct_fields
60
+ end
61
+
62
+ def parse(tokens)
63
+ while tokens.size > 0
64
+ if tokens[0] == "type"
65
+ name = tokens[1]
66
+ tokens, type = self.parse(tokens[2..])
67
+ @definitions[name.to_sym] = type
68
+ elsif tokens[0] == "map"
69
+ raise SchemaParsingException("Map must be followed by a '[' eg. map[string]data") if tokens[1] != :open_brace
70
+ tokens, map_from_type = parse(tokens[2..])
71
+ raise SchemaParsingException("Map to type must be followed by a ']' eg. map[string]data") if tokens[0] != :close_brace
72
+ tokens, map_to_type = parse(tokens[1..])
73
+ return tokens, Bare.Map(map_from_type,map_to_type)
74
+ elsif tokens[0] == "enum"
75
+ name = tokens[1]
76
+ raise SchemaParsingException("Enum must be followed by a '{'") if tokens[2] != :open_block
77
+ tokens, enum = parse_enum(tokens[3..])
78
+ @definitions[name.to_sym] = enum
79
+ return tokens, enum
80
+ elsif tokens[0] == :open_brace
81
+ tokens, arr_type = parse(tokens[2..])
82
+ return tokens, Bare.Array(arr_type)
83
+ elsif tokens[0] == :open_block
84
+ tokens, struct_fields = parse_struct(tokens[1..])
85
+ strct = Bare.Struct(struct_fields)
86
+ return tokens, strct
87
+ elsif @primitives.include?(tokens[0])
88
+ type = @primitives[tokens[0]]
89
+ return tokens[1..], type
90
+ else
91
+ raise SchemaParsingException.new("Unable to parse token: #{tokens[0]}")
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+ def parser(tokens, definitions = {})
99
+ parser = Parser.new
100
+ parser.parse(tokens)
101
+ return parser.definitions
102
+ end
@@ -148,7 +148,6 @@ class BareTypes
148
148
  key = output[:value]
149
149
  output = @to.decode(output[:rest])
150
150
  hash[key] = output[:value]
151
- hash[key] = output[:value]
152
151
  end
153
152
  return {value: hash, rest: output[:rest]}
154
153
  end
@@ -236,7 +235,7 @@ class BareTypes
236
235
  output = Uint.new.decode(msg)
237
236
  rest = output[:rest]
238
237
  dataSize = output[:value]
239
- return {value: rest[0..dataSize], rest: rest[dataSize..rest.size]}
238
+ return {value: rest[0..dataSize-1], rest: rest[dataSize..]}
240
239
  end
241
240
  end
242
241
 
@@ -506,7 +505,7 @@ class BareTypes
506
505
  @valToInt = {}
507
506
  raise BareException("Enum must initialized with a hash from integers to anything") if !source.is_a?(Hash)
508
507
  raise BareException("Enum must have unique positive integer assignments") if Set.new(source.keys).size != source.keys.size
509
- raise BareException("Enum must have unique values") if source.values.to_set.size != source.values.size
508
+ raise EnumValueError("Enum must have unique values") if source.values.to_set.size != source.values.size
510
509
  source.each do |k, v|
511
510
  raise("Enum keys must be positive integers") if k < 0
512
511
  @intToVal[k.to_i] = v
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bare-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Tracy-Amoroso
@@ -10,7 +10,8 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2020-10-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Implements the bare message encoding
13
+ description: The first implementation of the BARE (Binary Application Record Encoding)
14
+ in Ruby. Includes schema parsing!
14
15
  email: n8@u.northwestern.edu
15
16
  executables: []
16
17
  extensions: []
@@ -18,6 +19,8 @@ extra_rdoc_files: []
18
19
  files:
19
20
  - "./lib/bare-rb.rb"
20
21
  - "./lib/exceptions.rb"
22
+ - "./lib/lexer.rb"
23
+ - "./lib/parser.rb"
21
24
  - "./lib/types.rb"
22
25
  homepage: https://github.com/n8ta/bare-rb
23
26
  licenses: