#include "ellipsis-expression.h"
#include "ellipsis-macros.h"
#include "utils/ellipsis-error.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
Macros | |
#define | ELLIPSIS_CONTRACT(COUNT, COND, ACTION, VERB, CSTR, CTYPE, ...) |
#define | ELLIPSIS_CONTRACT_CHECK_STATIC(CTYPE, COND, CSTR, ...) |
#define | ELLIPSIS_CONTRACT_ICE_OR_TRUE(...) |
#define | ELLIPSIS_CONTRACT_IMPL(COUNT, COND, ACTION, VERB, CSTR, CTYPE, ...) |
#define | ELLIPSIS_CONTRACT_VIOLATION(COUNT, VERB, CTYPE, CSTR, ...) |
#define | ELLIPSIS_STR32_LITERAL ELLIPSIS_STR32_LITERAL_LOCAL |
#define | ELLIPSIS_TEST_ICE(...) (false ? ELLIPSIS_TO_VOIDS(__VA_ARGS__) : (ellipsis‿contracts‿is_ice*)nullptr) |
#define | ELLIPSIS_TO_VOIDS(...) ((void*)((uintptr_t)((__VA_ARGS__)-(__VA_ARGS__)))) |
#define | STRINGIFY(...) STRINGIFY_(__VA_ARGS__) |
#define | STRINGIFY_(...) #__VA_ARGS__ |
Typedefs | |
typedef struct ellipsis‿contracts‿is_ice | ellipsis‿contracts‿is_ice |
Functions | |
ellipsis‿token * | ellipsis‿expression‿evaluate (ellipsis‿token‿list *expr) |
bool | ellipsis‿expression‿make_integer (ellipsis‿token *t) |
static ellipsis‿token * | ellipsis‿expression‿prefix (ellipsis‿token‿list *e) |
static ellipsis‿token * | ellipsis‿expression‿prefix_or_recurse (ellipsis‿token‿list *e) |
static ellipsis‿token * | ellipsis‿expression‿recurse (ellipsis‿token‿list *e) |
void | ellipsis‿expression‿resolve_defined (ellipsis‿token‿list *in, ellipsis‿token‿list *out) |
static ellipsis‿token * | ellipsis‿expression‿ternary (ellipsis‿token‿list *e, bool yes) |
Variables | |
thread_local bool volatile | ellipsis‿contracts‿ignore‿dynamic |
thread_local bool volatile | ellipsis‿contracts‿proceed‿dynamic |
thread_local bool volatile | ellipsis‿contracts‿verbose‿dynamic |
This implements expression parsing with a handful of recursive functions that call each other.
The main work is done in ellipsis‿expression‿recurse
which treats the case of chains of binary operators. Prefix and ternary operators then need some special treatment.
#define ELLIPSIS_CONTRACT | ( | COUNT, | |
COND, | |||
ACTION, | |||
VERB, | |||
CSTR, | |||
CTYPE, | |||
... | |||
) |
#define ELLIPSIS_CONTRACT_CHECK_STATIC | ( | CTYPE, | |
COND, | |||
CSTR, | |||
... | |||
) |
#define ELLIPSIS_CONTRACT_ICE_OR_TRUE | ( | ... | ) |
#define ELLIPSIS_CONTRACT_IMPL | ( | COUNT, | |
COND, | |||
ACTION, | |||
VERB, | |||
CSTR, | |||
CTYPE, | |||
... | |||
) |
#define ELLIPSIS_CONTRACT_VIOLATION | ( | COUNT, | |
VERB, | |||
CTYPE, | |||
CSTR, | |||
... | |||
) |
#define ELLIPSIS_STR32_LITERAL ELLIPSIS_STR32_LITERAL_LOCAL |
#define ELLIPSIS_TEST_ICE | ( | ... | ) | (false ? ELLIPSIS_TO_VOIDS(__VA_ARGS__) : (ellipsis‿contracts‿is_ice*)nullptr) |
#define ELLIPSIS_TO_VOIDS | ( | ... | ) | ((void*)((uintptr_t)((__VA_ARGS__)-(__VA_ARGS__)))) |
#define STRINGIFY | ( | ... | ) | STRINGIFY_(__VA_ARGS__) |
#define STRINGIFY_ | ( | ... | ) | #__VA_ARGS__ |
typedef struct ellipsis‿contracts‿is_ice ellipsis‿contracts‿is_ice |
ellipsis‿token * ellipsis‿expression‿evaluate | ( | ellipsis‿token‿list * | expr | ) |
This function uses a trick to ensure that only operators of the same priority appear on the same level of parenthesis. It consists of surrounding the expression with a large number of matching pairs of parenthesis and then surrounding operators by anti-matching pairs. For example an expression with addition and multiplication
a * b + c
is then replaced by
(...(( a )*( b ))+(( c ))...) ^^^ * has priority 1 ^^^^^ + has priority 2
(...(( a )*( b ))+(( c ))...) ^^^^^^^^^^^ inner expression (...( ab )+(( c ))...) ^^^^^^^^^^^^^^^^^^^^^ outer expression
start inner defer anchor at level 1
DEFER_TYPE needs a semicolon
defer needs braces and a semicolon
defer needs braces and a semicolon
defer needs braces and a semicolon
end inner defer anchor, level 1
References ellipsis‿expression‿recurse(), ellipsis‿token‿list‿all(), ellipsis‿token‿list‿append(), ellipsis‿token‿list‿close(), ellipsis‿token‿list‿destroy(), exp_signed, exp_unsigned, ellipsis‿token::next, and punctuator.
Referenced by _Atomic(), ellipsis‿macros‿cb‿evaluate(), and evaluate_expression().
bool ellipsis‿expression‿make_integer | ( | ellipsis‿token * | t | ) |
References ellipsis‿str32‿dup, exp_signed, exp_unsigned, and numeral.
Referenced by ellipsis‿directive‿line_common(), and ellipsis‿expression‿prefix().
|
static |
References ellipsis‿str32::array, ellipsis‿token::cat, ellipsis‿token::contents, ellipsis‿expression‿make_integer(), ellipsis‿expression‿prefix_or_recurse(), ellipsis‿token‿list‿pop(), exp_signed, exp_unsigned, nominal, numeral, punctuator, and ellipsis‿token::value.
Referenced by ellipsis‿expression‿prefix_or_recurse().
|
static |
References ellipsis‿expression‿prefix(), ellipsis‿expression‿recurse(), ellipsis‿token‿list‿pop(), ellipsis‿token‿list‿top(), and first.
Referenced by ellipsis‿expression‿prefix(), ellipsis‿expression‿recurse(), and ellipsis‿expression‿ternary().
|
static |
start inner defer anchor at level 1
DEFER_TYPE needs a semicolon
start inner defer anchor at level 2
defer needs braces and a semicolon
start inner defer anchor at level 3
defer needs braces and a semicolon
end inner defer anchor, level 3
end inner defer anchor, level 2
end inner defer anchor, level 1
References ellipsis‿str32::array, ellipsis‿token::cat, ellipsis‿token::contents, ellipsis‿expression‿prefix_or_recurse(), ellipsis‿expression‿ternary(), ellipsis‿str32‿fputs(), ellipsis‿token‿list‿pop(), ellipsis‿token‿list‿top(), ELLIPSIS_CONTRACT, exp_signed, exp_unsigned, first, ellipsis‿str32::length, punctuator, and ellipsis‿token::value.
Referenced by ellipsis‿expression‿evaluate(), and ellipsis‿expression‿prefix_or_recurse().
void ellipsis‿expression‿resolve_defined | ( | ellipsis‿token‿list * | in, |
ellipsis‿token‿list * | out | ||
) |
start inner defer anchor at level 1
defer needs braces and a semicolon
start inner defer anchor at level 2
defer needs braces and a semicolon
end inner defer anchor, level 2
start inner defer anchor at level 2
defer needs braces and a semicolon
end inner defer anchor, level 2
end inner defer anchor, level 1
References ellipsis‿token::callback, ellipsis‿token::cat, ellipsis‿token::contents, ellipsis‿macros‿find(), ellipsis‿macros‿functions_find(), ellipsis‿str32‿delete(), ellipsis‿token‿list‿all(), ellipsis‿token‿list‿append(), ellipsis‿token‿list‿close(), ellipsis‿token‿list‿collect_call(), ellipsis‿token‿list‿destroy(), ellipsis‿token‿list‿pop(), ellipsis‿token‿list‿top(), ELLIPSIS_CONTRACT, exp_signed, and ellipsis‿str32::length.
Referenced by ellipsis‿macros‿cb‿evaluate(), and evaluate_expression().
|
static |
This supposes that only ? and : operators appear on the same level of parenthesis.
start inner defer anchor at level 1
DEFER_TYPE needs a semicolon
start inner defer anchor at level 2
defer needs braces and a semicolon
end inner defer anchor, level 2
defer needs braces and a semicolon
end inner defer anchor, level 1
References ellipsis‿token::cat, ellipsis‿expression‿prefix_or_recurse(), ellipsis‿expression‿ternary(), ellipsis‿str32‿fputs(), ellipsis‿token‿list‿pop(), exp_signed, exp_unsigned, and ellipsis‿token::value.
Referenced by ellipsis‿expression‿recurse(), and ellipsis‿expression‿ternary().
|
extern |
|
extern |
|
extern |