Files
metadesk/examples/expr/expr_c_like.mdesk
T
2021-10-10 16:52:09 -07:00

73 lines
2.7 KiB
Plaintext

/*
** Example: c like expressions
**
** Input for the expression parser in expr_c_like.c
**
** Many of the expressions in this example have to be expressed in slightly
** unusual ways (from the perspective of C) to make them work in the Metadesk
** grammar before the expression parser deals with them. Each of those cases in
** this file have comments explaining it. - The rule of thumb is that sometimes
** an expression needs to be placed in parentheses if it gets complicated.
**
** It may be useful to review intro/sets.mdesk to understand some the cases.
*/
a: 100;
// @notes If we just have `b: array[a];` here the Metadesk parser will emit a
// warning and the tree won't have the shape we actually intend. We want:
// b: (array [a])
// But we would actually get
// b: array
// [a]
// This happens because `b` is an "implicitly delimited" set, which _CANNOT_
// contain explicitly delimited sets like `[a]`
// Adding the parentheses makes this into an "explicitly delimited" set which
// _CAN_ contain `[a]`.
b: ( array[a] );
c: sizeof xyz;
d: i*stride + j;
e: 2.71828;
// @notes The Metadesk expression parser uses parentheses like any common
// expression parser, but we have to remember that before the expression
// parser sees those parentheses, they actually get handled by the main
// Metadesk parser and turned into set nodes.
//
// If we just have `f: (H << 16) | (H >> 16);` here, then the tree we would
// get from the Metadesk parser is:
// f: (H << 16)
// |
// (H >> 16)
//
// Again the solution is to use an extra set of parentheses to tell the
// Metadesk parser that `(H << 16) | (H >> 16)` are all children of `f`.
f: ( (H << 16) | (H >> 16) );
// @notes This time the problem is that we want the set delimiters `{}` to be
// visible to the expression parser. If we just have `g: {0, +1, -1}` then
// the shape of the tree becomes:
// g: (0, + 1, - 1)
//
// If we want to treat `{...}` as a leaf in an expression in this case we
// need an extra set of parentheses so that `{...}` is a child of g and not
// just the delimiters of the g node itself.
g: ( {0, +1, -1} );
h: foo.bar;
// @notes In these cases we want a nameless node that just contains an
// expression. We need parentheses so that these form sets. An alternative in
// this case is to have the C code do more work to use the `;` separators to
// find the beginning and ending of expressions like these. What we have here
// keeps things very simple.
(i += 1);
(j = 0);
(k = i*stride + j);
// @notes This one is pretty much the same as the first one, postfix index and
// postfix call operators both introduce an explicitly delimited set, which
// can't be contained in an implicitly delimited set.
l: ( foo(bar, array[k], sizeof c) );