git.haldean.org wallbot / 5241533
parsing for registers haldean 3 years ago
5 changed file(s) with 199 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
1919 #include "meka.h"
2020 #include "meka_internal.h"
2121
22 #include <stdio.h>
23 #include <string.h>
24
2225 #define _is_whitespace(c) ((c) == ' ' || (c) == '\n' || (c) == '\r')
2326
2427 static meka_word p[4096];
2528 static uint16_t pn = 0;
29
30 meka_register reg[] = {
31 { .name = {'c', 'a', 'l', 0 }, .typ = meka_tag_bool },
32 { .name = {'g', 'o', 0, 0 }, .typ = meka_tag_bool },
33 { .name = {'j', 'o', 'g', 'q'}, .typ = meka_tag_qvec },
34 { .name = {'j', 'o', 'g', 'r'}, .typ = meka_tag_rvec },
35 { .name = {'m', 'l', 'd', 0 }, .typ = meka_tag_chan },
36 { .name = {'m', 'l', 'e', 0 }, .typ = meka_tag_chan },
37 { .name = {'m', 'l', 's', 0 }, .typ = meka_tag_chan },
38 { .name = {'m', 'r', 'd', 0 }, .typ = meka_tag_chan },
39 { .name = {'m', 'r', 'e', 0 }, .typ = meka_tag_chan },
40 { .name = {'m', 'r', 's', 0 }, .typ = meka_tag_chan },
41 { .name = {'p', 'e', 'n', 0 }, .typ = meka_tag_bool },
42 { .name = {'p', 'i', 'v', 'l'}, .typ = meka_tag_rvec },
43 { .name = {'p', 'i', 'v', 'r'}, .typ = meka_tag_rvec },
44 { .name = {'r', 'a', 'd', 'l'}, .typ = meka_tag_int },
45 { .name = {'r', 'a', 'd', 'r'}, .typ = meka_tag_int },
46 { .name = {'s', 't', 'e', 'p'}, .typ = meka_tag_int },
47 };
48 const size_t regn = sizeof(reg) / sizeof(*reg);
2649
2750 void
2851 meka_skip_to_token(meka_source *src)
6386 return res->len > 0;
6487 }
6588
66 meka_value
67 meka_parse_number(meka_token *t)
89 meka_parse_result
90 meka_parse_number(meka_token *t, meka_value *v)
6891 {
6992 int32_t res;
7093 int8_t s;
95118 * early-reject those and then don't have to check for overflow when
96119 * building the 32-bit intermediate result. */
97120 if (t->len - i > 9)
98 return meka_bad_value;
121 {
122 /* distinguish between not-a-number and number-but-overflow */
123 for (; i < t->len; i++)
124 if ('0' > t->data[i] || t->data[i] > '9')
125 return PARSE_FAIL;
126 return PARSE_INVALID_VALUE;
127 }
99128
100129 for (; i < t->len; i++)
101130 {
103132 if ('0' <= c && c <= '9')
104133 res = res * 10 + (c - '0');
105134 else
106 return meka_bad_value;
135 return PARSE_FAIL;
107136 }
108137
109138 if (res > 0xFFFFFFF)
110 return meka_bad_value;
111 return meka_pack(int, s * res);
139 return PARSE_INVALID_VALUE;
140 *v = meka_pack(int, s * res);
141 return PARSE_OK;
142 }
143
144 meka_parse_result
145 meka_parse_register(meka_token *t, meka_value *v)
146 {
147 size_t i;
148 meka_register test = {0};
149
150 if (t->len <= 0 || t->len > 5 || t->data[0] != '%')
151 return PARSE_FAIL;
152
153 for (i = 1; i < t->len; i++)
154 test.name[i - 1] = t->data[i];
155
156 for (i = 0; i < regn; i++)
157 {
158 if (test.namebits == reg[i].namebits)
159 {
160 *v = meka_pack(reg, i);
161 return PARSE_OK;
162 }
163 }
164 return PARSE_INVALID_VALUE;
112165 }
113166
114167 int
116169 {
117170 meka_token tok;
118171 meka_value v;
172 meka_parse_result rc;
119173
120174 pn = 0;
121175 while (meka_next_token(&tok, src))
122176 {
123 v = meka_parse_number(&tok);
124 if (v != meka_bad_value)
125 {
126 p[pn++].v = v;
127 continue;
177 rc = meka_parse_number(&tok, &p[pn++].v);
178 if (rc == PARSE_OK)
179 continue;
180 if (rc == PARSE_INVALID_VALUE)
181 {
182 printf("number '");
183 fwrite(tok.data, 1, tok.len, stdout);
184 printf("' overflows a 28-bit signed value\n");
185 goto fail;
186 }
187
188 rc = meka_parse_register(&tok, &v);
189 if (rc == PARSE_OK)
190 continue;
191 if (rc == PARSE_INVALID_VALUE)
192 {
193 printf("register ");
194 fwrite(tok.data, 1, tok.len, stdout);
195 printf(" doesn't exist\n");
196 goto fail;
128197 }
129198 }
130199
131200 return pn;
132 }
201
202 fail:
203 pn = 0;
204 memset(p, 0, sizeof(p));
205 return pn;
206 }
1919 #pragma once
2020 #include <stdint.h>
2121
22 static const uint32_t meka_tag_bool = 0x00000000;
23 static const uint32_t meka_tag_int = 0x00000001;
24 static const uint32_t meka_tag_qvec = 0x00000002;
25 static const uint32_t meka_tag_rvec = 0x00000003;
26 static const uint32_t meka_tag_reg = 0x00000004;
27 static const uint32_t meka_tag_chan = 0x00000005;
28 static const uint32_t meka_tag_cset = 0x00000006;
29 static const uint32_t meka_tag_none = 0x00000007;
30 static const uint32_t meka_tag_mask = 0xFFFFFFF8;
22 /* these are #defines instead of const uint32_t's so that they can be
23 * used to initialize static structures */
24 #define meka_tag_bool ((uint32_t) 0x00000000)
25 #define meka_tag_int ((uint32_t) 0x00000001)
26 #define meka_tag_qvec ((uint32_t) 0x00000002)
27 #define meka_tag_rvec ((uint32_t) 0x00000003)
28 #define meka_tag_reg ((uint32_t) 0x00000004)
29 #define meka_tag_chan ((uint32_t) 0x00000005)
30 #define meka_tag_cset ((uint32_t) 0x00000006)
31 #define meka_tag_none ((uint32_t) 0x00000007)
32 #define meka_tag_mask ((uint32_t) 0xFFFFFFF8)
3133
3234 typedef uint32_t meka_value;
3335
2828 uint8_t marker;
2929 } meka_token;
3030
31 static const uint8_t meka_word_none = 0x00;
32 static const uint8_t meka_word_int = 0x01;
33 static const uint8_t meka_word_reg = 0x02;
34 static const uint8_t meka_word_txt = 0x03;
35
3631 typedef struct
3732 {
3833 union
4136 meka_token t;
4237 };
4338 } meka_word;
39
40 typedef struct
41 {
42 union
43 {
44 char name[4];
45 uint32_t namebits;
46 };
47 uint32_t typ;
48 } meka_register;
49
50 typedef enum
51 {
52 PARSE_OK,
53 /* parsed successfully but the value it represents is invalid */
54 PARSE_INVALID_VALUE,
55 /* couldn't parse it at all */
56 PARSE_FAIL,
57 } meka_parse_result;
4646 return ok;
4747 }
4848
49 test_t
50 pack_register()
51 {
52 meka_value v;
53
54 v = meka_pack(reg, 1);
55 assert((int32_t) meka_unpack(v) == 1);
56 assert(meka_tag(v) == meka_tag_reg);
57
58 return ok;
59 }
60
4961 int main()
5062 {
5163 init();
5264 run(pack_positive_int);
5365 run(pack_negative_int);
66 run(pack_register);
5467 finish();
5568 }
2020 #include "meka_internal.h"
2121 #include "unit.h"
2222
23 extern meka_value meka_parse_number(meka_token *t);
23 #include <string.h>
24
25 extern meka_parse_result meka_parse_number(meka_token *t, meka_value *v);
26 extern meka_parse_result meka_parse_register(meka_token *t, meka_value *v);
27 extern meka_register reg[];
28
29 #define parse_number_case(str, num) \
30 t.data = str; t.len = strlen(str); \
31 assert(meka_parse_number(&t, &v) == PARSE_OK); \
32 assert(v == meka_pack(int, num));
33
34 #define parse_number_case_fail(str, code) \
35 t.data = str; t.len = strlen(str); \
36 assert(meka_parse_number(&t, &v) == code);
2437
2538 test_t
2639 parse_number()
2740 {
2841 meka_token t;
42 meka_value v;
2943
30 t.data = "0"; t.len = 1;
31 assert(meka_parse_number(&t) == meka_pack(int, 0));
32
33 t.data = "1"; t.len = 1;
34 assert(meka_parse_number(&t) == meka_pack(int, 1));
35
36 t.data = "+1"; t.len = 2;
37 assert(meka_parse_number(&t) == meka_pack(int, 1));
38
39 t.data = "-1"; t.len = 2;
40 assert(meka_parse_number(&t) == meka_pack(int, -1));
41
42 t.data = "00000"; t.len = 5;
43 assert(meka_parse_number(&t) == meka_pack(int, 0));
44 parse_number_case("0", 0);
45 parse_number_case("1", 1);
46 parse_number_case("+1", 1);
47 parse_number_case("-1", -1);
48 parse_number_case("00000", 0);
4449
4550 /* Not a digit overflow, because they're all "leading" zeroes */
46 t.data = "0000000000000000"; t.len = 16;
47 assert(meka_parse_number(&t) == meka_pack(int, 0));
51 parse_number_case("0000000000000000", 0);
4852
4953 /* Digit overflow */
50 t.data = "1000000000000000"; t.len = 16;
51 assert(meka_parse_number(&t) == meka_bad_value);
54 parse_number_case_fail("1000000000000000", PARSE_INVALID_VALUE);
5255
5356 /* 28-bit overflow, with admissable number of digits */
54 t.data = "268435457"; t.len = 9;
55 assert(meka_parse_number(&t) == meka_bad_value);
57 parse_number_case_fail("268435457", PARSE_INVALID_VALUE);
5658
5759 /* 28-bit int-max */
58 t.data = "268435455"; t.len = 9;
59 assert(meka_parse_number(&t) == meka_pack(int, 268435455));
60 parse_number_case("268435455", 268435455);
6061
6162 /* 28-bit int-min */
62 t.data = "-268435455"; t.len = 10;
63 assert(meka_parse_number(&t) == meka_pack(int, -268435455));
63 parse_number_case("-268435455", -268435455);
64
65 /* Not even a number */
66 parse_number_case_fail("1234asdf", PARSE_FAIL);
67
68 /* Overflows on length but is also not a number */
69 parse_number_case_fail("123456789asdf", PARSE_FAIL);
70
71 return ok;
72 }
73
74 #define parse_register_case(str, type) \
75 t.data = str; t.len = strlen(str); \
76 assert(meka_parse_register(&t, &v) == PARSE_OK); \
77 assert(reg[meka_unpack(v)].typ == meka_tag_ ## type);
78
79 #define parse_register_case_fail(str, code) \
80 t.data = str; t.len = strlen(str); \
81 assert(meka_parse_register(&t, &v) == code);
82
83 test_t
84 parse_register()
85 {
86 meka_token t;
87 meka_value v;
88
89 parse_register_case("%cal", bool);
90 parse_register_case("%go", bool);
91 parse_register_case("%jogq", qvec);
92 parse_register_case("%jogr", rvec);
93 parse_register_case("%mld", chan);
94 parse_register_case("%mle", chan);
95 parse_register_case("%mls", chan);
96 parse_register_case("%mrd", chan);
97 parse_register_case("%mre", chan);
98 parse_register_case("%mrs", chan);
99 parse_register_case("%pen", bool);
100 parse_register_case("%pivl", rvec);
101 parse_register_case("%pivr", rvec);
102 parse_register_case("%radl", int);
103 parse_register_case("%radr", int);
104 parse_register_case("%step", int);
105
106 parse_register_case_fail("asdf", PARSE_FAIL);
107 parse_register_case_fail("%asdf", PARSE_INVALID_VALUE);
64108
65109 return ok;
66110 }
70114 {
71115 init();
72116 run(parse_number);
117 run(parse_register);
73118 finish();
74119 }