literals.c (2789B)
1 #include <string.h> 2 3 #include "internal.h" 4 5 void toy_emit_int_bytes(ToyParser* p, uint64_t v, uint8_t* buf, size_t n) { 6 size_t i; 7 (void)p; 8 for (i = 0; i < n; ++i) buf[i] = (uint8_t)(v >> (i * 8u)); 9 } 10 11 int toy_parse_number_arg(ToyParser* p, int64_t* out) { 12 if (p->cur.kind != TOK_NUMBER || p->cur.is_float) { 13 toy_error(p, p->cur.loc, "expected integer constant"); 14 return 0; 15 } 16 *out = p->cur.int_value; 17 toy_parser_advance(p); 18 return 1; 19 } 20 21 int toy_parse_string_sym(ToyParser* p, KitSym* out, size_t* len_out) { 22 char buf[256]; 23 size_t len; 24 if (p->cur.kind != TOK_STRING || p->cur.text_len < 2) { 25 toy_error(p, p->cur.loc, "expected string literal"); 26 return 0; 27 } 28 len = p->cur.text_len - 2; 29 if (len >= sizeof buf) { 30 toy_error(p, p->cur.loc, "string literal too long"); 31 return 0; 32 } 33 memcpy(buf, p->cur.text + 1, len); 34 buf[len] = '\0'; 35 *out = kit_sym_intern(p->c, (KitSlice){.s = buf, .len = len}); 36 if (len_out) *len_out = len; 37 toy_parser_advance(p); 38 return 1; 39 } 40 41 int toy_parse_string_bytes(ToyParser* p, uint8_t* out, size_t cap, 42 size_t* len_out) { 43 const uint8_t* cur; 44 const uint8_t* end; 45 size_t n = 0; 46 if (p->cur.kind != TOK_STRING || p->cur.text_len < 2) { 47 toy_error(p, p->cur.loc, "expected string literal"); 48 return 0; 49 } 50 cur = p->cur.text + 1; 51 end = p->cur.text + p->cur.text_len - 1; 52 while (cur < end) { 53 uint8_t c = *cur++; 54 if (c == '\\' && cur < end) { 55 uint8_t esc = *cur++; 56 if (esc == '0') 57 c = 0; 58 else if (esc == 'n') 59 c = '\n'; 60 else if (esc == 't') 61 c = '\t'; 62 else if (esc == '"' || esc == '\\') 63 c = esc; 64 else if (esc == 'x' && cur + 1 < end) { 65 uint8_t hi = *cur++; 66 uint8_t lo = *cur++; 67 uint8_t hv = (hi >= '0' && hi <= '9') ? (uint8_t)(hi - '0') 68 : (hi >= 'a' && hi <= 'f') ? (uint8_t)(hi - 'a' + 10) 69 : (hi >= 'A' && hi <= 'F') ? (uint8_t)(hi - 'A' + 10) 70 : 255; 71 uint8_t lv = (lo >= '0' && lo <= '9') ? (uint8_t)(lo - '0') 72 : (lo >= 'a' && lo <= 'f') ? (uint8_t)(lo - 'a' + 10) 73 : (lo >= 'A' && lo <= 'F') ? (uint8_t)(lo - 'A' + 10) 74 : 255; 75 if (hv == 255 || lv == 255) { 76 toy_error(p, p->cur.loc, "invalid hex escape"); 77 return 0; 78 } 79 c = (uint8_t)((hv << 4) | lv); 80 } else { 81 toy_error(p, p->cur.loc, "unknown string escape"); 82 return 0; 83 } 84 } 85 if (n >= cap) { 86 toy_error(p, p->cur.loc, "string literal too long"); 87 return 0; 88 } 89 out[n++] = c; 90 } 91 *len_out = n; 92 toy_parser_advance(p); 93 return 1; 94 }