00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define _GNU_SOURCE
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <inttypes.h>
00029 #include <stdint.h>
00030 #include <math.h>
00031 #include <limits.h>
00032 #include <errno.h>
00033 #include <unistd.h>
00034 #include <string.h>
00035 #include <stdarg.h>
00036 #include <arpa/inet.h>
00037 #include <yyast/leaf.h>
00038 #include <yyast/count.h>
00039 #include <yyast/utils.h>
00040 #include <yyast/error.h>
00041
00042 ya_t ya_literal(const char * restrict name, ya_type_t type, const void * restrict buf, size_t buf_size)
00043 {
00044 size_t aligned_buf_size = ya_align64(buf_size);
00045
00046 ya_t r = {
00047 .type = type,
00048 .size = sizeof (ya_node_t) + aligned_buf_size,
00049 .position = ya_previous_position,
00050 };
00051
00052
00053
00054 r.node = calloc(1, r.size);
00055 r.node->name = htonll(ya_create_name(name));
00056 r.node->size = htonll(sizeof (ya_node_t) + aligned_buf_size);
00057 r.node->type = r.type;
00058 r.node->position.file = htonl(r.position.file);
00059 r.node->position.line = htonl(r.position.line);
00060 r.node->position.column = htonl(r.position.column);
00061
00062 memcpy(r.node->data, buf, buf_size);
00063
00064 memset(&r.node->data[buf_size], 0, aligned_buf_size - buf_size);
00065 return r;
00066 }
00067
00068
00069 typedef union {
00070 double d;
00071 uint64_t u;
00072 int64_t i;
00073 } translate_t;
00074
00075 ya_t ya_binary_float(const char * restrict name, const char * restrict buf, size_t buf_size __attribute__((unused)), int base __attribute__((unused)), int nr_bits __attribute__((unused)))
00076 {
00077 translate_t t;
00078 char *endptr;
00079
00080 t.d = strtold(buf, &endptr);
00081 if (buf == endptr) {
00082 ya_error("Could not convert real value '%s'", buf);
00083 }
00084
00085 if ((t.d == HUGE_VALL || t.d == -HUGE_VALL) && errno == ERANGE) {
00086 ya_error("Could not convert real value '%s', overflow", buf);
00087 }
00088
00089 if ((t.d == 0.0 || t.d == -0.0) && errno == ERANGE) {
00090 ya_error("Could not convert real value '%s', underflow", buf);
00091 }
00092
00093 t.u = htonll(t.u);
00094 return ya_literal(name, YA_NODE_TYPE_BINARY_FLOAT, &t.u, sizeof (t.u));
00095 }
00096
00097 ya_t ya_integer(const char * restrict name, ya_type_t type, const char * restrict buf, size_t buf_size, int base)
00098 {
00099 int i = 0;
00100 char c;
00101 uint128_t value;
00102 uint128_t value128;
00103 uint64_t value64;
00104 int digit;
00105
00106 value = 0;
00107 for (i = 0; i < buf_size; i++) {
00108 c = buf[i];
00109
00110 if (base == 32) {
00111
00112 if (c >= 'a' && c <= 'z') { digit = c - 'a'; }
00113 else if (c >= 'A' && c <= 'Z') { digit = c - 'A'; }
00114 else if (c >= '2' && c <= '7') { digit = c - '2' + 26; }
00115 else { digit = base; }
00116
00117 } else if (base >= 37 && base <= 64) {
00118
00119 if (c >= 'A' && c <= 'Z') { digit = c - 'A'; }
00120 else if (c >= 'a' && c <= 'z') { digit = c - 'a' + 26; }
00121 else if (c >= '0' && c <= '9') { digit = c - '0' + 52; }
00122 else if (c == '+' ) { digit = 62; }
00123 else if (c == '/' ) { digit = 63; }
00124 else { digit = base; }
00125
00126 } else if (base >= 0 && base <= 36) {
00127
00128 if (c >= '0' && c <= '9') { digit = c - '0'; }
00129 else if (c >= 'A' && c <= 'Z') { digit = c - 'A' + 10; }
00130 else if (c >= 'a' && c <= 'z') { digit = c - 'a' + 10; }
00131 else { digit = base; }
00132
00133 } else {
00134 fprintf(stderr, "ya_integer does not implement a base above 64.\n");
00135 abort();
00136 }
00137
00138 if (digit < base) {
00139
00140 value *= base;
00141 if (value + digit < value) {
00142 ya_error("Overflow of integer literal");
00143 }
00144 value += digit;
00145 }
00146 }
00147
00148 if (value <= UINT64_MAX) {
00149 value64 = htonll(value);
00150 return ya_literal(name, type, &value64, sizeof(value64));
00151 } else {
00152 value128 = htonlll(value);
00153 return ya_literal(name, type, &value128, sizeof(value128));
00154 }
00155 }
00156
00157 ya_t ya_text(const char * restrict name, const char * restrict buf, size_t buf_size)
00158 {
00159 return ya_literal(name, YA_NODE_TYPE_TEXT, buf, buf_size);
00160 }
00161
00162 ya_t ya_leaf(const char * restrict name)
00163 {
00164 return ya_literal(name, YA_NODE_TYPE_LEAF, NULL, 0);
00165 }
00166
00167 ya_t ya_null(void)
00168 {
00169 return ya_literal("#null", YA_NODE_TYPE_NULL, NULL, 0);
00170 }
00171
00172 ya_t ya_positive_integer(const char * restrict name, const char * restrict buf, size_t buf_size, int base)
00173 {
00174 return ya_integer(name, YA_NODE_TYPE_POSITIVE_INTEGER, buf, buf_size, base);
00175 }
00176
00177 ya_t ya_negative_integer(const char * restrict name, const char * restrict buf, size_t buf_size, int base)
00178 {
00179 return ya_integer(name, YA_NODE_TYPE_NEGATIVE_INTEGER, buf, buf_size, base);
00180 }
00181