Make statement blocks explicit in the AST.
authorRyan C. Gordon <icculus@icculus.org>
Wed, 13 Oct 2010 17:56:41 -0400
changeset 917 85afb474f99d
parent 916 3738cd265707
child 918 b7644336f032
Make statement blocks explicit in the AST. This is needed so we can correctly handle scope during semantic analysis.
mojoshader_compiler.c
mojoshader_parser_hlsl.lemon
--- a/mojoshader_compiler.c	Wed Oct 13 17:29:28 2010 -0400
+++ b/mojoshader_compiler.c	Wed Oct 13 17:56:41 2010 -0400
@@ -114,6 +114,7 @@
     AST_COMPUNIT_END_RANGE,
 
     AST_STATEMENT_START_RANGE,
+    AST_STATEMENT_BLOCK,
     AST_STATEMENT_EMPTY,
     AST_STATEMENT_EXPRESSION,
     AST_STATEMENT_IF,
@@ -393,6 +394,13 @@
 typedef Statement ContinueStatement;
 typedef Statement DiscardStatement;
 
+typedef struct BlockStatement  // something enclosed in "{}" braces.
+{
+    ASTNode ast;
+    struct Statement *next;
+    Statement *statements;  // list of statements enclosed by this block.
+} BlockStatement;
+
 typedef struct ReturnStatement
 {
     ASTNode ast;
@@ -1135,6 +1143,22 @@
     Free(ctx, stmt);
 } // delete_return_statement
 
+static Statement *new_block_statement(Context *ctx, Statement *statements)
+{
+    NEW_AST_NODE(retval, BlockStatement, AST_STATEMENT_BLOCK);
+    retval->next = NULL;
+    retval->statements = statements;
+    return (Statement *) retval;
+} // new_block_statement
+
+static void delete_block_statement(Context *ctx, BlockStatement *stmt)
+{
+    DELETE_AST_NODE(stmt);
+    delete_statement(ctx, stmt->statements);
+    delete_statement(ctx, stmt->next);
+    Free(ctx, stmt);
+} // delete_statement_block
+
 static Statement *new_for_statement(Context *ctx, VariableDeclaration *decl,
                                     Expression *initializer,
                                     Expression *looptest, Expression *counter,
@@ -1393,6 +1417,7 @@
     {
         #define DELETE_STATEMENT(typ, cls, fn) case AST_STATEMENT_##typ: \
             delete_##fn##_statement(ctx, (cls *) stmt); break;
+        DELETE_STATEMENT(BLOCK, BlockStatement, block);
         DELETE_STATEMENT(EMPTY, EmptyStatement, empty);
         DELETE_STATEMENT(IF, IfStatement, if);
         DELETE_STATEMENT(SWITCH, SwitchStatement, switch);
@@ -1727,12 +1752,18 @@
         case AST_STATEMENT_IF:
             printf("if (");
             print_ast(((IfStatement *) ast)->expr);
-            printf(") {\n");
+            printf(")\n");
+
+            if (((IfStatement *) ast)->statement->ast.type != AST_STATEMENT_BLOCK)
+                indent++;
             for (i = 0; i < indent; i++) printf("    ");
-            indent++;
-            print_ast(((IfStatement *) ast)->statement);
-            indent--;
-            printf("}\n");
+            print_ast(((ForStatement *) ast)->statement);
+            if (((IfStatement *) ast)->statement->ast.type != AST_STATEMENT_BLOCK)
+            {
+                printf("\n");
+                indent--;
+            } // if
+
             for (i = 0; i < indent; i++) printf("    ");
             print_ast(((Statement *) ast)->next);
             break;
@@ -1797,6 +1828,19 @@
             print_ast(((Statement *) ast)->next);
             break;
 
+        case AST_STATEMENT_BLOCK:
+            printf("{\n");
+            indent++;
+            for (i = 0; i < indent; i++) printf("    ");
+            print_ast(((BlockStatement *) ast)->statements);
+            printf("\n");
+            indent--;
+            for (i = 0; i < indent; i++) printf("    ");
+            printf("}\n");
+            for (i = 0; i < indent; i++) printf("    ");
+            print_ast(((Statement *) ast)->next);
+            break;
+
         case AST_STATEMENT_FOR:
             if (((ForStatement *) ast)->unroll == 0)
                 printf("[loop] ");
@@ -1815,16 +1859,18 @@
             print_ast(((ForStatement *) ast)->looptest);
             printf("; ");
             print_ast(((ForStatement *) ast)->counter);
+
             printf(")\n");
-            for (i = 0; i < indent; i++) printf("    ");
-            printf("{\n");
-            indent++;
+            if (((ForStatement *) ast)->statement->ast.type != AST_STATEMENT_BLOCK)
+                indent++;
             for (i = 0; i < indent; i++) printf("    ");
             print_ast(((ForStatement *) ast)->statement);
-            printf("\n");
-            indent--;
-            for (i = 0; i < indent; i++) printf("    ");
-            printf("}\n");
+            if (((ForStatement *) ast)->statement->ast.type != AST_STATEMENT_BLOCK)
+            {
+                printf("\n");
+                indent--;
+            } // if
+
             for (i = 0; i < indent; i++) printf("    ");
             print_ast(((Statement *) ast)->next);
             break;
@@ -1841,15 +1887,19 @@
             } // else if
 
             printf("do\n");
-            for (i = 0; i < indent; i++) printf("    ");
-            printf("{\n");
-            indent++;
+
+            if (((DoStatement *) ast)->statement->ast.type != AST_STATEMENT_BLOCK)
+                indent++;
             for (i = 0; i < indent; i++) printf("    ");
-            print_ast(((DoStatement *) ast)->statement);
-            printf("\n");
-            indent--;
+            print_ast(((ForStatement *) ast)->statement);
+            if (((DoStatement *) ast)->statement->ast.type != AST_STATEMENT_BLOCK)
+            {
+                printf("\n");
+                indent--;
+            } // if
+
             for (i = 0; i < indent; i++) printf("    ");
-            printf("} while (");
+            printf("while (");
             print_ast(((DoStatement *) ast)->expr);
             printf(");\n");
             for (i = 0; i < indent; i++) printf("    ");
@@ -1870,15 +1920,17 @@
             printf("while (");
             print_ast(((WhileStatement *) ast)->expr);
             printf(")\n");
-            for (i = 0; i < indent; i++) printf("    ");
-            printf("{\n");
-            indent++;
+
+            if (((WhileStatement *) ast)->statement->ast.type != AST_STATEMENT_BLOCK)
+                indent++;
             for (i = 0; i < indent; i++) printf("    ");
-            print_ast(((WhileStatement *) ast)->statement);
-            printf("\n");
-            indent--;
-            for (i = 0; i < indent; i++) printf("    ");
-            printf("}\n");
+            print_ast(((ForStatement *) ast)->statement);
+            if (((WhileStatement *) ast)->statement->ast.type != AST_STATEMENT_BLOCK)
+            {
+                printf("\n");
+                indent--;
+            } // if
+
             for (i = 0; i < indent; i++) printf("    ");
             print_ast(((Statement *) ast)->next);
             break;
@@ -1890,8 +1942,7 @@
                 printf(" ");
                 print_ast(((ReturnStatement *) ast)->expr);
             } // if
-            printf(";\n");
-            for (i = 0; i < indent; i++) printf("    ");
+            printf(";");
             print_ast(((Statement *) ast)->next);
             break;
 
@@ -1918,14 +1969,8 @@
             {
                 printf("\n");
                 for (i = 0; i < indent; i++) printf("    ");
-                printf("{\n");
-                indent++;
-                for (i = 0; i < indent; i++) printf("    ");
                 print_ast(((CompilationUnitFunction *) ast)->definition);
-                indent--;
-                printf("\n");
-                for (i = 0; i < indent; i++) printf("    ");
-                printf("}\n\n");
+                printf("\n\n");
             } // else
             for (i = 0; i < indent; i++) printf("    ");
             print_ast(((CompilationUnit *) ast)->next);
--- a/mojoshader_parser_hlsl.lemon	Wed Oct 13 17:29:28 2010 -0400
+++ b/mojoshader_parser_hlsl.lemon	Wed Oct 13 17:56:41 2010 -0400
@@ -345,8 +345,8 @@
 
 %type statement_block { Statement * }
 %destructor statement_block { delete_statement(ctx, $$); }
-statement_block(A) ::= LBRACE RBRACE. { A = new_empty_statement(ctx); }
-statement_block(A) ::= LBRACE statement_list(B) RBRACE. { REVERSE_LINKED_LIST(Statement, B); A = B; }
+statement_block(A) ::= LBRACE RBRACE. { A = new_block_statement(ctx, NULL); }
+statement_block(A) ::= LBRACE statement_list(B) RBRACE. { REVERSE_LINKED_LIST(Statement, B); A = new_block_statement(ctx, B); }
 
 %type statement_list { Statement * }
 %destructor statement_list { delete_statement(ctx, $$); }