quby-compiler 0.6.6 → 0.6.8
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 +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/quby/compiler/dsl/helpers.rb +1 -1
- data/lib/quby/compiler/dsl/sexp_variable_builder.rb +25 -1
- data/lib/quby/compiler/entities/sexp_variable.rb +50 -4
- data/lib/quby/compiler/entities/sexp_variables.rb +51 -5
- data/lib/quby/compiler/version.rb +1 -1
- metadata +45 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 01cfba3183d5a4279b2c73b3c9cee99b676bb878fe4fb41750966dff9f3cee05
|
|
4
|
+
data.tar.gz: b73b3f4426dc2a4f995fd03164a49ef65d27a723d7de870fdeceaebf26efecc0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7babf0bc0256ed62390f442b34104eaf64778ad04a563fa3ffd239091bcca67f0d3058a42a67df4b8db50a12a8e6bd064636f290cc519233065c7d0a18175e9f
|
|
7
|
+
data.tar.gz: c65d1f03ed2219c8b3704a843323ef92bb019baef95889ee86d40ecc67fb4f4eda5a2bdb5905adf652178657b783232c85353db0fb726076efbaad1ea342ce21
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
# 0.6.8
|
|
2
|
+
|
|
3
|
+
* dsl_quby2.json: Add count_selected to s-expressions.
|
|
4
|
+
* dsl_quby2.json: Add cond, true and false to s-expressions. cond evaluates the body of the first clause whose test is true; each body must have the same type.
|
|
5
|
+
* dsl_quby2.json: single_select_label variables (also via cond) must be declared `type: :quest_i18n_key` and are serialized with that type.
|
|
6
|
+
|
|
7
|
+
# 0.6.7
|
|
8
|
+
|
|
9
|
+
* dsl_quby2.json: Add single_select_label to s-expressions.
|
|
10
|
+
|
|
1
11
|
# 0.6.6
|
|
2
12
|
|
|
3
13
|
* dsl: Add Question#subtype (iso_country_number).
|
|
@@ -19,6 +19,14 @@ module Quby::Compiler
|
|
|
19
19
|
Entities::SexpVariables::StringValue.new(op: :string_value, key: key)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def single_select_label(key)
|
|
23
|
+
Entities::SexpVariables::SingleSelectLabel.new(op: :single_select_label, key: key)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def count_selected(key)
|
|
27
|
+
Entities::SexpVariables::CountSelected.new(key: key)
|
|
28
|
+
end
|
|
29
|
+
|
|
22
30
|
def number_value(key)
|
|
23
31
|
Entities::SexpVariables::NumberValue.new(op: :number_value, key: key)
|
|
24
32
|
end
|
|
@@ -49,6 +57,16 @@ module Quby::Compiler
|
|
|
49
57
|
Entities::SexpVariables::NumberMethod.new(op: :round, value: value)
|
|
50
58
|
end
|
|
51
59
|
|
|
60
|
+
# cond(clause(gt(left: number_value(:v_1), right: 2), 4), clause(true, 0))
|
|
61
|
+
# evaluates the body of the first clause whose test is true, so `clause(true, ...)` acts as the default case.
|
|
62
|
+
def cond(*clauses)
|
|
63
|
+
Entities::SexpVariables::Cond.new(op: :cond, clauses:)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def clause(test, body)
|
|
67
|
+
Entities::SexpVariables::Cond::Clause.new(test: wrap_scalars(test), body: wrap_scalars(body))
|
|
68
|
+
end
|
|
69
|
+
|
|
52
70
|
def build
|
|
53
71
|
Entities::SexpVariable.new(key:, calculation:, type:)
|
|
54
72
|
end
|
|
@@ -63,9 +81,15 @@ module Quby::Compiler
|
|
|
63
81
|
case value
|
|
64
82
|
when Numeric
|
|
65
83
|
Entities::SexpVariables::Number.new(op: :number, value: value)
|
|
84
|
+
when true
|
|
85
|
+
Entities::SexpVariables::True.new
|
|
86
|
+
when false
|
|
87
|
+
Entities::SexpVariables::False.new
|
|
88
|
+
when String
|
|
89
|
+
fail ArgumentError, "string literals are not supported in sexp_variables (they can't be translated), use string_value(:key) to reference a string question."
|
|
66
90
|
else
|
|
67
91
|
value
|
|
68
|
-
end
|
|
92
|
+
end
|
|
69
93
|
end
|
|
70
94
|
end
|
|
71
95
|
end
|
|
@@ -14,7 +14,11 @@ module Quby::Compiler::Entities
|
|
|
14
14
|
def validate(questionnaire, calculation: self.calculation)
|
|
15
15
|
validate_node(calculation, questionnaire:, type:)
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
def as_json(options = nil)
|
|
19
|
+
{key:, type: node_type(calculation), calculation:}.as_json(options)
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
private
|
|
19
23
|
|
|
20
24
|
def validate_node(node, questionnaire:, type:)
|
|
@@ -27,6 +31,12 @@ module Quby::Compiler::Entities
|
|
|
27
31
|
when SexpVariables::StringValue
|
|
28
32
|
validate_question_exist(questionnaire, node)
|
|
29
33
|
validate_value_is_string(questionnaire, node)
|
|
34
|
+
when SexpVariables::SingleSelectLabel
|
|
35
|
+
validate_question_exist(questionnaire, node)
|
|
36
|
+
validate_value_is_single_select(questionnaire, node)
|
|
37
|
+
when SexpVariables::CountSelected
|
|
38
|
+
validate_question_exist(questionnaire, node)
|
|
39
|
+
validate_value_is_multi_select(questionnaire, node)
|
|
30
40
|
when SexpVariables::NumberReducer
|
|
31
41
|
node.values.each do |value|
|
|
32
42
|
validate_node(value, questionnaire:, type: :number)
|
|
@@ -38,13 +48,17 @@ module Quby::Compiler::Entities
|
|
|
38
48
|
when SexpVariables::Comparer
|
|
39
49
|
validate_node(node.left, questionnaire:, type: :number)
|
|
40
50
|
validate_node(node.right, questionnaire:, type: :number)
|
|
51
|
+
when SexpVariables::Cond
|
|
52
|
+
node.clauses.each do |clause|
|
|
53
|
+
validate_node(clause.test, questionnaire:, type: :boolean)
|
|
54
|
+
|
|
55
|
+
validate_node(clause.body, questionnaire:, type: type)
|
|
56
|
+
end
|
|
41
57
|
end
|
|
42
58
|
end
|
|
43
59
|
|
|
44
60
|
def validate_type(node, type:)
|
|
45
|
-
return if type ==
|
|
46
|
-
return if type == :boolean && SexpVariables::BooleanType === node
|
|
47
|
-
return if type == :string && SexpVariables::StringValue === node
|
|
61
|
+
return if type == node_type(node)
|
|
48
62
|
|
|
49
63
|
fail "sexp_variable #{key} has invalid type #{node.class} for expected type #{type}."
|
|
50
64
|
end
|
|
@@ -65,6 +79,23 @@ module Quby::Compiler::Entities
|
|
|
65
79
|
fail "sexp_variable #{key} uses non-numeric question #{sexp.key} for number_value."
|
|
66
80
|
end
|
|
67
81
|
|
|
82
|
+
def validate_value_is_single_select(questionnaire, sexp)
|
|
83
|
+
question = questionnaire.question_hash[sexp.key]
|
|
84
|
+
case question
|
|
85
|
+
when Questions::RadioQuestion, Questions::SelectQuestion
|
|
86
|
+
return
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
fail "sexp_variable #{key} uses non-single-select question #{sexp.key} for single_select_label."
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def validate_value_is_multi_select(questionnaire, sexp)
|
|
93
|
+
question = questionnaire.question_hash[sexp.key]
|
|
94
|
+
return if Questions::CheckboxQuestion === question
|
|
95
|
+
|
|
96
|
+
fail "sexp_variable #{key} uses non-multi-select question #{sexp.key} for count_selected."
|
|
97
|
+
end
|
|
98
|
+
|
|
68
99
|
def validate_value_is_string(questionnaire, sexp)
|
|
69
100
|
question = questionnaire.question_hash[sexp.key]
|
|
70
101
|
case question
|
|
@@ -74,5 +105,20 @@ module Quby::Compiler::Entities
|
|
|
74
105
|
|
|
75
106
|
fail "sexp_variable #{key} uses non-string question #{sexp.key} for string_value."
|
|
76
107
|
end
|
|
108
|
+
|
|
109
|
+
def node_type(node)
|
|
110
|
+
case(node)
|
|
111
|
+
when SexpVariables::Cond # match first, since it's in all types.
|
|
112
|
+
node_type(node.clauses.first.body)
|
|
113
|
+
when SexpVariables::BooleanType
|
|
114
|
+
:boolean
|
|
115
|
+
when SexpVariables::NumericType
|
|
116
|
+
:number
|
|
117
|
+
when SexpVariables::StringType
|
|
118
|
+
:string
|
|
119
|
+
when SexpVariables::QuestI18nKeyType
|
|
120
|
+
:quest_i18n_key
|
|
121
|
+
end
|
|
122
|
+
end
|
|
77
123
|
end
|
|
78
124
|
end
|
|
@@ -4,28 +4,62 @@ module Quby::Compiler::Entities
|
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
# recursive dependencies, we so we define the classes first.
|
|
7
|
+
class Cond < Base; end
|
|
8
|
+
|
|
7
9
|
class NumberValue < Base; end
|
|
8
10
|
class Number < Base; end
|
|
9
11
|
class NumberReducer < Base; end
|
|
10
12
|
class NumberMethod < Base; end
|
|
13
|
+
class CountSelected < Base; end
|
|
14
|
+
|
|
11
15
|
class BooleanReducer < Base; end
|
|
12
16
|
class Comparer < Base; end
|
|
17
|
+
class True < Base; end
|
|
18
|
+
class False < Base; end
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
class StringValue < Base; end
|
|
21
|
+
class SingleSelectLabel < Base; end
|
|
22
|
+
|
|
23
|
+
NumericType = Number | NumberReducer | NumberMethod | NumberValue | CountSelected | Cond
|
|
24
|
+
BooleanType = BooleanReducer | Comparer | True | False | Cond
|
|
25
|
+
StringType = StringValue | Cond
|
|
26
|
+
QuestI18nKeyType = SingleSelectLabel | Cond
|
|
27
|
+
AllTypes = NumericType | BooleanType | StringType | QuestI18nKeyType
|
|
16
28
|
|
|
17
29
|
class NumberValue
|
|
18
30
|
attribute :op, Quby::Types::Symbol.enum(:number_value)
|
|
19
31
|
attribute :key, Quby::Types::Symbol
|
|
20
32
|
end
|
|
21
33
|
|
|
22
|
-
class StringValue
|
|
34
|
+
class StringValue
|
|
23
35
|
attribute :op, Quby::Types::Symbol.enum(:string_value)
|
|
24
36
|
attribute :key, Quby::Types::Symbol
|
|
25
37
|
end
|
|
26
38
|
|
|
39
|
+
# label of the selected option of a single-select (radio, scale, select) question.
|
|
40
|
+
class SingleSelectLabel
|
|
41
|
+
attribute :op, Quby::Types::Symbol.enum(:single_select_label)
|
|
42
|
+
attribute :key, Quby::Types::Symbol
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# returning a Boolean: always true. Used as the default case of a cond.
|
|
46
|
+
class True
|
|
47
|
+
attribute :op, Quby::Types::Symbol.default(:true).enum(:true)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# returning a Boolean: always false.
|
|
51
|
+
class False
|
|
52
|
+
attribute :op, Quby::Types::Symbol.default(:false).enum(:false)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# number of selected options of a multi-select (check_box) question.
|
|
56
|
+
class CountSelected
|
|
57
|
+
attribute :op, Quby::Types::Symbol.default(:count_selected).enum(:count_selected)
|
|
58
|
+
attribute :key, Quby::Types::Symbol
|
|
59
|
+
end
|
|
60
|
+
|
|
27
61
|
class Number
|
|
28
|
-
attribute :op, Quby::Types::Symbol.enum(:number)
|
|
62
|
+
attribute :op, Quby::Types::Symbol.enum(:number)
|
|
29
63
|
attribute :value, Quby::Types::Integer | Quby::Types::Float
|
|
30
64
|
end
|
|
31
65
|
|
|
@@ -50,8 +84,20 @@ module Quby::Compiler::Entities
|
|
|
50
84
|
|
|
51
85
|
# returning a Number
|
|
52
86
|
class NumberMethod
|
|
53
|
-
attribute :op, Quby::Types::Symbol.enum(:round)
|
|
87
|
+
attribute :op, Quby::Types::Symbol.enum(:round)
|
|
54
88
|
attribute :value, NumericType
|
|
55
89
|
end
|
|
90
|
+
|
|
91
|
+
# evaluates the body of the first clause whose test is true.
|
|
92
|
+
# Each body should have the same type, which determines the result type.
|
|
93
|
+
class Cond
|
|
94
|
+
class Clause < Base
|
|
95
|
+
attribute :test, BooleanType
|
|
96
|
+
attribute :body, AllTypes
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
attribute :op, Quby::Types::Symbol.enum(:cond)
|
|
100
|
+
attribute :clauses, Quby::Types::Array.of(Clause).constrained(min_size: 1)
|
|
101
|
+
end
|
|
56
102
|
end
|
|
57
103
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: quby-compiler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marten Veldthuis
|
|
@@ -13,44 +13,62 @@ dependencies:
|
|
|
13
13
|
name: activemodel
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.1'
|
|
19
|
+
- - "<"
|
|
17
20
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '
|
|
21
|
+
version: '8.2'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">"
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '
|
|
28
|
+
version: '7.1'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '8.2'
|
|
26
32
|
- !ruby/object:Gem::Dependency
|
|
27
33
|
name: actionview
|
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
|
29
35
|
requirements:
|
|
30
|
-
- - "
|
|
36
|
+
- - ">"
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '7.1'
|
|
39
|
+
- - "<"
|
|
31
40
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
41
|
+
version: '8.2'
|
|
33
42
|
type: :runtime
|
|
34
43
|
prerelease: false
|
|
35
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
45
|
requirements:
|
|
37
|
-
- - "
|
|
46
|
+
- - ">"
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '7.1'
|
|
49
|
+
- - "<"
|
|
38
50
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '
|
|
51
|
+
version: '8.2'
|
|
40
52
|
- !ruby/object:Gem::Dependency
|
|
41
53
|
name: activesupport
|
|
42
54
|
requirement: !ruby/object:Gem::Requirement
|
|
43
55
|
requirements:
|
|
44
|
-
- - "
|
|
56
|
+
- - ">"
|
|
45
57
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
58
|
+
version: '7.1'
|
|
59
|
+
- - "<"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '8.2'
|
|
47
62
|
type: :runtime
|
|
48
63
|
prerelease: false
|
|
49
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
65
|
requirements:
|
|
51
|
-
- - "
|
|
66
|
+
- - ">"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '7.1'
|
|
69
|
+
- - "<"
|
|
52
70
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
71
|
+
version: '8.2'
|
|
54
72
|
- !ruby/object:Gem::Dependency
|
|
55
73
|
name: csv
|
|
56
74
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -149,6 +167,20 @@ dependencies:
|
|
|
149
167
|
- - ">="
|
|
150
168
|
- !ruby/object:Gem::Version
|
|
151
169
|
version: '0'
|
|
170
|
+
- !ruby/object:Gem::Dependency
|
|
171
|
+
name: appraisal
|
|
172
|
+
requirement: !ruby/object:Gem::Requirement
|
|
173
|
+
requirements:
|
|
174
|
+
- - ">="
|
|
175
|
+
- !ruby/object:Gem::Version
|
|
176
|
+
version: '0'
|
|
177
|
+
type: :development
|
|
178
|
+
prerelease: false
|
|
179
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
180
|
+
requirements:
|
|
181
|
+
- - ">="
|
|
182
|
+
- !ruby/object:Gem::Version
|
|
183
|
+
version: '0'
|
|
152
184
|
email:
|
|
153
185
|
- marten@veldthuis.com
|
|
154
186
|
executables:
|