Skip to content

Commit c6b35a6

Browse files
committed
support parsing numbers as integers
1 parent b6c4dd5 commit c6b35a6

File tree

3 files changed

+70
-28
lines changed

3 files changed

+70
-28
lines changed

examples/03_parsing_database.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
typedef struct {
1010
const char *name;
11-
double age;
11+
long long age;
1212
const char *location;
13-
double body_count;
13+
double cash;
1414
} Person;
1515

1616
typedef struct {
@@ -26,11 +26,11 @@ bool parse_person(Jimp *jimp, Person *p)
2626
if (strcmp(jimp->member, "name") == 0) {
2727
if (!jimp_string(jimp, &p->name)) return false;
2828
} else if (strcmp(jimp->member, "age") == 0) {
29-
if (!jimp_number(jimp, &p->age)) return false;
29+
if (!jimp_int(jimp, &p->age)) return false;
3030
} else if (strcmp(jimp->member, "location") == 0) {
3131
if (!jimp_string(jimp, &p->location)) return false;
32-
} else if (strcmp(jimp->member, "body_count") == 0) {
33-
if (!jimp_number(jimp, &p->body_count)) return false;
32+
} else if (strcmp(jimp->member, "cash") == 0) {
33+
if (!jimp_float(jimp, &p->cash)) return false;
3434
} else {
3535
jimp_unknown_member(jimp);
3636
return false;
@@ -54,14 +54,14 @@ bool parse_people(Jimp *jimp, People *ps)
5454

5555
void print_person(const Person *p)
5656
{
57-
printf("name = %s\n", p->name);
58-
printf("age = %lf\n", p->age);
59-
printf("location = %s\n", p->location);
60-
printf("body_count = %lf\n", p->body_count);
57+
printf("name = %s\n", p->name);
58+
printf("age = %lld\n", p->age);
59+
printf("location = %s\n", p->location);
60+
printf("cash = $%.2lf\n", p->cash);
6161
}
6262

6363
typedef struct {
64-
long *items;
64+
JimpNumber *items;
6565
size_t count;
6666
size_t capacity;
6767
} Numbers;
@@ -92,7 +92,7 @@ int main()
9292
} else if (strcmp(jimp.member, "number") == 0) {
9393
if (!jimp_array_begin(&jimp)) return 1;
9494
while (jimp_array_item(&jimp)) {
95-
double x = 0;
95+
JimpNumber x = {0};
9696
if (!jimp_number(&jimp, &x)) return 1;
9797
da_append(&xs, x);
9898
}
@@ -109,8 +109,11 @@ int main()
109109
printf("\n");
110110
}
111111
printf("------------------------------\n");
112-
da_foreach(long, x, &xs) {
113-
printf("%ld ", *x);
112+
da_foreach(JimpNumber, x, &xs) {
113+
if (x->type == JIMP_INTEGER)
114+
printf("%lld ", x->value.i);
115+
else
116+
printf("%lf ", x->value.f);
114117
}
115118
printf("\n");
116119

examples/database.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,66 @@
11
{
2-
"number": [69, 420, 1337, 80085],
2+
"number": [69, 420, 1337, 80085, .69, 42.123, 123., 9007199254740993, 9007199254740993.0],
33
"profile": [
44
{
55
"location": "Wonderland",
66
"location": "Wonderland",
7-
"body_count": 150,
7+
"cash": 1.5,
88
"name": "Alice Smith",
99
"age": 34
1010
},
1111
{
1212
"name": "Bob Johnson",
1313
"age": 45,
1414
"location": "Atlantis",
15-
"body_count": 300
15+
"cash": 3
1616
},
1717
{
1818
"name": "Charlie Brown",
1919
"age": 28,
2020
"location": "Chocolate Factory",
21-
"body_count": 200
21+
"cash": 2
2222
},
2323
{
2424
"name": "Diana Prince",
2525
"age": 32,
2626
"location": "Themyscira",
27-
"body_count": 250
27+
"cash": 2.5
2828
},
2929
{
3030
"name": "Ethan Hunt",
3131
"age": 40,
3232
"location": "Mission HQ",
33-
"body_count": 350
33+
"cash": 3.5
3434
},
3535
{
3636
"name": "Fiona Apple",
3737
"age": 37,
3838
"location": "Music City",
39-
"body_count": 180
39+
"cash": 1.8
4040
},
4141
{
4242
"name": "George Lucas",
4343
"age": 75,
4444
"location": "Galaxy Far Far Away",
45-
"body_count": 500
45+
"cash": 5
4646
},
4747
{
4848
"name": "Hannah Montana",
4949
"age": 25,
5050
"location": "Nashville",
51-
"body_count": 100
51+
"cash": 1
5252
},
5353
{
5454
"name": "Ian Malcolm",
5555
"age": 60,
5656
"location": "Jurassic Park",
57-
"body_count": 400
57+
"cash": 4
5858
},
5959
{
6060
"name": "Jessica Rabbit",
6161
"age": 30,
6262
"location": "Toontown",
63-
"body_count": 220
63+
"cash": 2.2
6464
}
6565
]
6666
}

jimp.h

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,21 @@ typedef enum {
3535
JIMP_NUMBER,
3636
} Jimp_Token;
3737

38+
typedef enum {
39+
JIMP_FLOATING,
40+
JIMP_INTEGER
41+
} JimpNumberType;
42+
43+
union JimpNumberValue {
44+
double f;
45+
long long i;
46+
};
47+
48+
typedef struct {
49+
JimpNumberType type;
50+
union JimpNumberValue value;
51+
} JimpNumber;
52+
3853
typedef struct {
3954
const char *file_path;
4055
const char *start;
@@ -47,14 +62,16 @@ typedef struct {
4762
char *string;
4863
size_t string_count;
4964
size_t string_capacity;
50-
double number;
65+
JimpNumber number;
5166

5267
const char *member;
5368
} Jimp;
5469

5570
// TODO: how do null-s fit into this entire system?
5671
bool jimp_bool(Jimp *jimp, bool *boolean);
57-
bool jimp_number(Jimp *jimp, double *number);
72+
bool jimp_number(Jimp *jimp, JimpNumber *number);
73+
bool jimp_float(Jimp *jimp, double *number);
74+
bool jimp_int(Jimp *jimp, long long *number);
5875
bool jimp_string(Jimp *jimp, const char **string);
5976
bool jimp_object_begin(Jimp *jimp);
6077
bool jimp_object_member(Jimp *jimp);
@@ -145,8 +162,16 @@ static bool jimp__get_token(Jimp *jimp)
145162
}
146163

147164
char *endptr = NULL;
148-
jimp->number = strtod(jimp->point, &endptr); // TODO: this implies that jimp->end is a valid address and *jimp->end == 0
165+
jimp->number.value.i = strtoull(jimp->point, &endptr, 0); // TODO: this implies that jimp->end is a valid address and *jimp->end == 0
166+
if (jimp->point != endptr && *endptr != '.') {
167+
jimp->number.type = JIMP_INTEGER;
168+
jimp->point = endptr;
169+
jimp->token = JIMP_NUMBER;
170+
return true;
171+
}
172+
jimp->number.value.f = strtod(jimp->point, &endptr);
149173
if (jimp->point != endptr) {
174+
jimp->number.type = JIMP_FLOATING;
150175
jimp->point = endptr;
151176
jimp->token = JIMP_NUMBER;
152177
return true;
@@ -298,13 +323,27 @@ bool jimp_bool(Jimp *jimp, bool *boolean)
298323
return true;
299324
}
300325

301-
bool jimp_number(Jimp *jimp, double *number)
326+
bool jimp_number(Jimp *jimp, JimpNumber *number)
302327
{
303328
if (!jimp__get_and_expect_token(jimp, JIMP_NUMBER)) return false;
304329
*number = jimp->number;
305330
return true;
306331
}
307332

333+
bool jimp_float(Jimp *jimp, double *number)
334+
{
335+
if (!jimp__get_and_expect_token(jimp, JIMP_NUMBER)) return false;
336+
*number = jimp->number.type == JIMP_FLOATING ? jimp->number.value.f : jimp->number.value.i;
337+
return true;
338+
}
339+
340+
bool jimp_int(Jimp *jimp, long long *number)
341+
{
342+
if (!jimp__get_and_expect_token(jimp, JIMP_NUMBER) || jimp->number.type != JIMP_INTEGER) return false;
343+
*number = jimp->number.value.i;
344+
return true;
345+
}
346+
308347
static bool jimp__get_and_expect_token(Jimp *jimp, Jimp_Token token)
309348
{
310349
if (!jimp__get_token(jimp)) return false;

0 commit comments

Comments
 (0)