From a0037d1a44f63bd8fdbb8b1de7b7a4ed2ab51558 Mon Sep 17 00:00:00 2001 From: jpekkila Date: Tue, 1 Oct 2019 21:14:33 +0300 Subject: [PATCH] Modified the syntax of writing real-valued literals with the DSL. Casts are not needed any more: f.ex. 1.0 is implicitly cast to AcReal. The syntax is now more consistent: reals must be explicitly written as a.b, where a and b are some integers. IMPORTANT: Previously the shorthands a. and .b were allowed, not anymore. Using those shorthands will result in a compilation error --- acc/src/acc.l | 5 +++-- acc/src/acc.y | 5 +++-- acc/src/ast.h | 42 +++++++++++++++++++--------------------- acc/src/code_generator.c | 21 ++++++++++++++++---- 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/acc/src/acc.l b/acc/src/acc.l index ac06712..c2a4cd7 100644 --- a/acc/src/acc.l +++ b/acc/src/acc.l @@ -37,8 +37,9 @@ L [a-zA-Z_] "return" { return RETURN; } -{D}+"."?{D}*[flud]? { return NUMBER; } /* Literals */ -"."{D}+[flud]? { return NUMBER; } +{D}+"."{D}+ { return REAL_NUMBER; } /* Literals */ +{D}+"."{D}+[fd]+ { return NUMBER; } +{D}+[lu]* { return NUMBER; } {L}({L}|{D})* { return IDENTIFIER; } \"(.)*\" { return IDENTIFIER; } /* String */ diff --git a/acc/src/acc.y b/acc/src/acc.y index 9e5cc93..39a5790 100644 --- a/acc/src/acc.y +++ b/acc/src/acc.y @@ -14,7 +14,7 @@ int yyget_lineno(); %} %token CONSTANT IN OUT UNIFORM -%token IDENTIFIER NUMBER +%token IDENTIFIER NUMBER REAL_NUMBER %token RETURN %token SCALAR VECTOR MATRIX SCALARFIELD SCALARARRAY %token VOID INT INT3 COMPLEX @@ -217,7 +217,8 @@ type_specifier: VOID identifier: IDENTIFIER { $$ = astnode_create(NODE_IDENTIFIER, NULL, NULL); astnode_set_buffer(yytext, $$); } ; -number: NUMBER { $$ = astnode_create(NODE_UNKNOWN, NULL, NULL); astnode_set_buffer(yytext, $$); } +number: REAL_NUMBER { $$ = astnode_create(NODE_REAL_NUMBER, NULL, NULL); astnode_set_buffer(yytext, $$); } + | NUMBER { $$ = astnode_create(NODE_UNKNOWN, NULL, NULL); astnode_set_buffer(yytext, $$); } ; return: RETURN { $$ = astnode_create(NODE_UNKNOWN, NULL, NULL); astnode_set_buffer(yytext, $$); } diff --git a/acc/src/ast.h b/acc/src/ast.h index 830a8c1..3868943 100644 --- a/acc/src/ast.h +++ b/acc/src/ast.h @@ -7,14 +7,15 @@ Statements: return value block */ -#include #include +#include #define BUFFER_SIZE (4096) #define GEN_ID(X) X #define GEN_STR(X) #X +// clang-format off #define FOR_NODE_TYPES(FUNC) \ FUNC(NODE_UNKNOWN), \ FUNC(NODE_DEFINITION), \ @@ -27,16 +28,18 @@ FUNC(NODE_FUNCTION_DECLARATION), \ FUNC(NODE_COMPOUND_STATEMENT), \ FUNC(NODE_FUNCTION_PARAMETER_DECLARATION), \ - FUNC(NODE_MULTIDIM_SUBSCRIPT_EXPRESSION) + FUNC(NODE_MULTIDIM_SUBSCRIPT_EXPRESSION), \ + FUNC(NODE_REAL_NUMBER) +// clang-format on -/* +/* // Recreating strdup is not needed when using the GNU compiler. // Let's also just say that anything but the GNU // compiler is NOT supported, since there are also -// some gcc-specific calls in the files generated +// some gcc-specific calls in the files generated // by flex and being completely compiler-independent is // not a priority right now -#ifndef strdup +#ifndef strdup static inline char* strdup(const char* in) { @@ -53,36 +56,32 @@ strdup(const char* in) #endif */ -typedef enum { - FOR_NODE_TYPES(GEN_ID), - NUM_NODE_TYPES -} NodeType; +typedef enum { FOR_NODE_TYPES(GEN_ID), NUM_NODE_TYPES } NodeType; typedef struct astnode_s { int id; struct astnode_s* lhs; struct astnode_s* rhs; - NodeType type; // Type of the AST node - char* buffer; // Indentifiers and other strings (empty by default) + NodeType type; // Type of the AST node + char* buffer; // Indentifiers and other strings (empty by default) - int token; // Type of a terminal (that is not a simple char) - int prefix; // Tokens. Also makes the grammar since we don't have - int infix; // to divide it into max two-child rules - int postfix; // (which makes it much harder to read) + int token; // Type of a terminal (that is not a simple char) + int prefix; // Tokens. Also makes the grammar since we don't have + int infix; // to divide it into max two-child rules + int postfix; // (which makes it much harder to read) } ASTNode; - static inline ASTNode* astnode_create(const NodeType type, ASTNode* lhs, ASTNode* rhs) { ASTNode* node = malloc(sizeof(node[0])); static int id_counter = 0; - node->id = id_counter++; - node->type = type; - node->lhs = lhs; - node->rhs = rhs; - node->buffer = NULL; + node->id = id_counter++; + node->type = type; + node->lhs = lhs; + node->rhs = rhs; + node->buffer = NULL; node->prefix = node->infix = node->postfix = 0; @@ -107,7 +106,6 @@ astnode_destroy(ASTNode* node) free(node); } - extern ASTNode* root; /* diff --git a/acc/src/code_generator.c b/acc/src/code_generator.c index c44e872..6b48f1b 100644 --- a/acc/src/code_generator.c +++ b/acc/src/code_generator.c @@ -395,16 +395,29 @@ traverse(const ASTNode* node) // Do a regular translation if (translate(node->token)) printf("%s ", translate(node->token)); - if (node->buffer) - printf("%s ", node->buffer); + if (node->buffer) { + if (node->type == NODE_REAL_NUMBER) { + printf("%s(%s) ", translate(SCALAR), + node->buffer); // Cast to correct precision + } + else { + printf("%s ", node->buffer); + } + } } } else { // Do a regular translation if (translate(node->token)) printf("%s ", translate(node->token)); - if (node->buffer) - printf("%s ", node->buffer); + if (node->buffer) { + if (node->type == NODE_REAL_NUMBER) { + printf("%s(%s) ", translate(SCALAR), node->buffer); // Cast to correct precision + } + else { + printf("%s ", node->buffer); + } + } } }