[examples] C like expressions comments

This commit is contained in:
Allen Webster
2021-10-10 16:52:09 -07:00
parent 07770d51d1
commit c968dd4329
2 changed files with 67 additions and 8 deletions
+12 -7
View File
@@ -1,7 +1,11 @@
/*
** Example: c like expressions
**
** TODO
** This example has the setup for parsing C expressions with the Metadesk
** expression parser.
**
** In the accompanying expr_c_like.mdesk there are more comments about using
** the expression system from the side of the Metadesk files.
**
*/
@@ -135,23 +139,24 @@ print_expression(FILE *out, MD_Expr *expr)
case MD_ExprOprKind_Prefix:
{
fprintf(out, "%.*s", MD_S8VArg(op->string));
MD_Node *node = expr->md_node;
fprintf(out, "%.*s(", MD_S8VArg(op->string));
print_expression(out, expr->unary_operand);
fprintf(out, ")");
}break;
case MD_ExprOprKind_Postfix:
{
fprintf(out, "(");
print_expression(out, expr->unary_operand);
MD_String8 op_string = op->string;
// TODO(allen): formalize 'set delimiter mask' into the library
MD_u64 set_delimiter_mask = 0x3F;
if ((expr->md_node->flags & set_delimiter_mask) != 0)
if ((expr->md_node->flags & MD_NodeFlag_MaskSetDelimiters) != 0)
{
fprintf(out, "%c...%c", op_string.str[0], op_string.str[1]);
fprintf(out, ")%c...%c", op_string.str[0], op_string.str[1]);
}
else
{
fprintf(out, "%.*s", MD_S8VArg(op_string));
fprintf(out, ")%.*s", MD_S8VArg(op_string));
}
}break;
+55 -1
View File
@@ -1,18 +1,72 @@
/*
** Example: c like expressions
**
** TODO
** 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) );