-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.rb
More file actions
113 lines (101 loc) · 3.13 KB
/
Copy pathparser.rb
File metadata and controls
113 lines (101 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
require "json/ld"
require_relative "constants"
require_relative "schema/base_types"
require_relative "schema/code"
require_relative "schema/data"
require_relative "schema/variable"
require_relative "schema/arithmetic"
require_relative "schema/logical"
require_relative "schema/comparation"
require_relative "schema/conversion"
require_relative "schema/bind"
require_relative "schema/io"
require_relative "schema/control"
class Hash
def ll_type
type = self[LinkedLang::TYPE_KEY]
type.filter!{|i| i.start_with?(LinkedLang::LL_NAMESPACE)} if type.is_a?(Array)
raise TypeError unless type.is_a?(String) || type.length <= 1
type = type[0] if type.is_a?(Array)
if type&.start_with?(LinkedLang::LL_NAMESPACE)
eval("LinkedLang::" + type.delete_prefix(LinkedLang::LL_NAMESPACE))
end
end
def ll_properties
ll_keys = self.keys.filter {|i| i.start_with?(LinkedLang::LL_NAMESPACE)}
properties = {}
ll_keys.each {|key| properties[key.delete_prefix(LinkedLang::LL_NAMESPACE)] = self[key]}
properties
end
def get_ll_property(key)
self[LinkedLang::LL_NAMESPACE + key]
end
def has_ll_property?(key)
self.has_key? LinkedLang::LL_NAMESPACE + key
end
end
module LinkedLang
class Parser
LL_CONTEXT = JSON.parse(File.read("#{__dir__}/context.jsonld"))[CONTEXT_KEY]
class << self
def parse(code)
raw_json = JSON.parse(code)
raw_json[CONTEXT_KEY] = addContext(raw_json[CONTEXT_KEY])
ldCode = JSON::LD::API.compact(raw_json, {})
if ldCode.ll_type == Code
parse_code ldCode
end
end
private
def addContext(context)
if context.nil?
LL_CONTEXT
elsif context.is_a?(Hash)
context.merge(LL_CONTEXT)
elsif context.is_a?(Array)
context << LL_CONTEXT
else
[context, LL_CONTEXT]
end
end
def parse_something(hash, type)
if type == Code
parse_code hash
elsif type <= Instruction || type <= Function
raise TypeError unless hash.ll_type <= type
parse_statement hash
end
end
def parse_code(hash)
content = []
raw_content = hash.get_ll_property("content")
if raw_content.nil?
# nothing to do
elsif raw_content.is_a?(Hash)
raise TypeError unless raw_content.ll_type <= Instruction
content = [parse_statement(raw_content)]
elsif raw_content.is_a?(Array)
raw_content.each do |item|
raise TypeError unless item.ll_type <= Instruction
content << parse_statement(item)
end
else
raise TypeError
end
Code.new content
end
def parse_statement(hash)
type = hash.ll_type
if type < Data || type <= Variable
return type.new(hash[VALUE_KEY])
end
raw_properties = hash.ll_properties
properties = {}
type.properties.each do |key, type|
properties["_#{key}".to_sym] = parse_something(raw_properties[key], type) if raw_properties.keys.include?(key)
end
type.new(**properties)
end
end
end
end