-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheml.h
195 lines (172 loc) · 6.15 KB
/
eml.h
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <stdint.h>
typedef uint32_t bool;
/*
* eml_number - An unsigned 32b fixed-point number
* MSB ("H") is reserved to "shift"
* decimal point by 2 places.
*
* Range: [0, 21,474,836.47]
* When storing integers, 7 bits are
* ignored as to constrain the number
* to be less than the MAX of its
* fractional counterpart.
*/
typedef uint32_t eml_number;
const uint32_t eml_number_mask = 0x7FFFFFFF;
const uint32_t eml_number_H = (0x1 << 31);
/*
* Parser Flag Types:
* eml_kind_flag - Which kind the parser is currently parsing excluding asymmetric since asymmetric is technically 2.
* eml_modifier_flag - Which modifer is being attached to the current work.
*/
typedef enum WorkKindFlag { none, standard, standard_varied } eml_kind_flag;
typedef enum AttachingModifierFlag { no_mod, weight_mod, rpe_mod } eml_modifier_flag;
/*
* eml_header_t - Header parameters used to define context.
*/
typedef struct HeaderToken {
struct HeaderToken *next;
char *parameter;
char *value;
} eml_header_t;
/*
* eml_reps - Number of reps (or number of seconds in a timeset) with optional modifiers.
*/
typedef struct Reps {
eml_number value;
union {
eml_number weight;
eml_number rpe;
} modifier;
enum {
unmodified,
unmodifiedFailure,
unmodifiedTime,
unmodifiedTimeFailure,
weight,
weightFailure,
timeWeight,
timeWeightFaliure,
rpe,
timeRPE,
} type;
} eml_reps;
/* EML Work (kind) */
/*
* No Work
* Description: No work for designated exercise. Often used in asymmetric work to define unilateral exercises.
* Example: "squat":;
*/
typedef bool eml_none_k;
/*
* Standard Work
* Description: Sets & Reps.
* Example: "squat":2x5; // two sets of five reps
*/
typedef struct Standard {
eml_reps reps;
uint32_t sets;
} eml_standard_k;
/*
* Standard Varied Work
* Description: Sets & Varying Reps.
* Example: "squat":2x(5,4); // two sets, one of five, then one of four
*/
typedef struct StandardVaried {
uint32_t sets;
eml_reps vReps[];
} eml_standard_varied_k;
/*
* Asymmetric
* Description: Exercise separated by left/right side, each with their own kind of work (excluding asymmetric)
* Example: "sl-rdl":5x5:4x4; // asymmetric single leg RDL's, five sets of five on left side, four sets of four on right.
*/
typedef struct Asymmetric {
eml_standard_k *left_standard_k;
eml_standard_varied_k *left_standard_varied_k;
eml_none_k *left_none_k;
eml_standard_k *right_standard_k;
eml_standard_varied_k *right_standard_varied_k;
eml_none_k *right_none_k;
} eml_asymmetric_k;
/* EML Tokens */
/*
* eml_single_t - A single exercise with a `name` and work.
*/
typedef struct Single {
char *name;
eml_none_k *no_work;
eml_standard_k *standard_work;
eml_standard_varied_k *standard_varied_work;
eml_asymmetric_k *asymmetric_work;
} eml_single_t;
/*
* eml_single_t - A linked list node holding onto eml_single_t within a super.
*/
typedef struct SuperMember {
eml_single_t *single;
struct SuperMember *next;
} eml_super_member_t;
/*
* eml_super_t - A collection of eml_super_member_t.
*/
typedef struct Superset {
uint32_t count;
eml_super_member_t *sets;
} eml_super_t;
/*
* eml_circuit_t - A collection of eml_super_member_t.
*/
typedef eml_super_t eml_circuit_t;
/* EML Objects */
/*
* eml_objtype - The EML Token type.
*/
typedef enum EMLObjtype { single, super, circuit } eml_objtype;
/*
* eml_obj - Wrapper around an EML Token.
*/
typedef struct EMLObj {
eml_objtype type;
void *data;
struct EMLObj *next;
} eml_obj;
/*
* eml_result - Parser output in the form of a linked list for the header and objects respectively
*/
typedef struct Result {
eml_header_t *header;
eml_obj *objs;
} eml_result;
/*
* Errors
*/
typedef enum Errors {
no_error, // Program terminated successfully (or there's a REALLY bad error)
unexpected_error,
allocation_error, // Malloc returned an error
name_work_separator_error, // You must include the ':' separator between NAME and WORK
extra_variable_reps_error, // Too many variable reps
missing_variable_reps_error, // Too few variable reps
none_work_to_failure_error, // You cannot make 'no work' to failure
to_failure_used_as_macro_error, // You cannot use 'to failure' as a macro
modifier_on_none_work_error, // You cannot add a modifier to 'no work'
time_macro_error, // You cannot attach time as a macro
fractional_sets_error, // You cannot have fractional sets
multiple_radix_points_error, // You cannot have multiple radix points
fractional_none_modifier_value_error, // You cannot have fractional reps / timesets
integral_overflow_error, // eml_number has overflowed integral part.
fp_overflow_error, // eml_number has overflowed while adding fp part.
too_many_fp_digits, // Too many numbers right of the radix point
empty_string_error, // Strings must be at least one character
string_length_error, // String must be 128 characters or less
missing_digit_following_radix_error, // There must be at least one digit following the radix point
missing_header_start_char, // eml string must start with header '{'
missing_version, // Header must contain version parameter
missing_weight_unit, // Header must contain weight unit parameter
bad_reps_type_transition, // eml string had an incorrect application of 'F', 'T', '@', '%', or some combination therein to REPS
rpe_to_failure, // You cannot make RPE to failure
} eml_error;
int parse(char *eml_string, eml_result **result);
void print_result(eml_result *result);
void free_result(eml_result *result);