From 5e48bf86933305a06744fce05ec2791c1bf81652 Mon Sep 17 00:00:00 2001 From: ryanfleury Date: Fri, 22 Jan 2021 14:58:33 -0700 Subject: [PATCH] C code generation sample, array expressions --- build.bat | 7 +++++++ samples/c_code_generation.c | 34 +++++++++++++++++++++++++++++++ source/md_impl.c | 40 ++++++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 samples/c_code_generation.c diff --git a/build.bat b/build.bat index 554e5d4..cbea7d1 100644 --- a/build.bat +++ b/build.bat @@ -10,6 +10,7 @@ echo ~~~ Build All Samples ~~~ cl %compile_flags% ..\samples\old_style_custom_layer.c cl %compile_flags% ..\samples\static_site_generator\static_site_generator.c cl %compile_flags% ..\samples\output_parse\output_parse.c +cl %compile_flags% ..\samples\c_code_generation.c echo. echo ~~~ Build All Tests ~~~ cl %compile_flags% ..\tests\sanity_tests.c @@ -48,3 +49,9 @@ popd popd popd popd + +echo. +echo ~~~ Running C Code Generation Sample ~~~ +pushd build +c_code_generation.exe +popd \ No newline at end of file diff --git a/samples/c_code_generation.c b/samples/c_code_generation.c new file mode 100644 index 0000000..816376d --- /dev/null +++ b/samples/c_code_generation.c @@ -0,0 +1,34 @@ +// Sample program that takes C-like information specified in the Metadesk format +// and generates valid C code from it. + +#include "md.h" +#include "md.c" + +int main(int argument_count, char **arguments) +{ + MD_String8 example_code = MD_S8Lit("@struct Foo:\n" + "{\n" + " a: S32,\n" + " b: *S32,\n" + " c: **void,\n" + " d: F32,\n" + " e: *[100]F32,\n" + " f: ([4 + 5]S32),\n" + "}\n\n"); + MD_Node *code = MD_ParseWholeString(MD_S8Lit("Generated Test Code"), example_code); + + printf("Source Metadesk Code:\n"); + printf("%.*s\n\n", MD_StringExpand(example_code)); + + printf("Generated C Code:\n"); + for(MD_EachNode(node, code->first_child)) + { + if(MD_NodeHasTag(node, MD_S8Lit("struct"))) + { + MD_OutputTree_C_Struct(stdout, node); + } + } + printf("\n\n"); + + return 0; +} \ No newline at end of file diff --git a/source/md_impl.c b/source/md_impl.c index 83128c6..2289e30 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -2375,6 +2375,7 @@ MD_ParseAsType(MD_Node *first, MD_Node *last) else if(_MD_NodeParse_ConsumeSet(ctx, &set)) { MD_Expr *t = MD_MakeExpr(set, MD_ExprKind_Array, MD_NilExpr(), MD_NilExpr()); + t->sub[1] = MD_ParseAsExpr(set->first_child, set->last_child); _MD_PushType(t); } else if(_MD_NodeParse_ConsumeAtom(ctx, &base_type)) @@ -2552,7 +2553,41 @@ MD_OutputExpr(FILE *file, MD_Expr *expr) { if(!MD_NodeIsNil(expr->node)) { - + _MD_ExprKindMetadata *metadata = _MD_MetadataFromExprKind(expr->kind); + switch(metadata->group) + { + case _MD_ExprKindGroup_Atom: + { + fprintf(file, "%.*s", MD_StringExpand(expr->node->string)); + }break; + + case _MD_ExprKindGroup_Binary: + { + fprintf(file, "("); + MD_OutputExpr(file, expr->sub[0]); + fprintf(file, " %s ", metadata->symbol); + MD_OutputExpr(file, expr->sub[1]); + fprintf(file, ")"); + }break; + + case _MD_ExprKindGroup_PreUnary: + { + fprintf(file, "%s", metadata->pre_symbol); + fprintf(file, "("); + MD_OutputExpr(file, expr->sub[0]); + fprintf(file, ")"); + }break; + + case _MD_ExprKindGroup_PostUnary: + { + fprintf(file, "("); + MD_OutputExpr(file, expr->sub[0]); + fprintf(file, ")"); + fprintf(file, "%s", metadata->post_symbol); + }break; + + default: break; + } } } @@ -2637,8 +2672,7 @@ MD_OutputType_C_RHS(FILE *file, MD_Expr *type) fprintf(file, ")"); } fprintf(file, "["); - // TODO(allen): MD_OutputExpr_C(file type->sub[1]); - fprintf(file, "\"C expressions not implemented\""); + MD_OutputExpr_C(file, type->sub[1]); fprintf(file, "]"); MD_OutputType_C_RHS(file, type->sub[0]); }break;