mirror of
https://github.com/Ed94/metadesk.git
synced 2026-06-13 07:52:22 -07:00
73 lines
2.7 KiB
Plaintext
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) );
|