From 6e403897d4b2afd0e2c9d38059386c1330c9c415 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 25 Oct 2010 16:47:26 -0400 Subject: [PATCH] Reworked AST to not use AST_OP_COMMA for function/constructor argument lists. --- mojoshader_compiler.c | 78 +++++++++++++++++++++++++++++++----- mojoshader_parser_hlsl.lemon | 18 +++++---- 2 files changed, 78 insertions(+), 18 deletions(-) diff --git a/mojoshader_compiler.c b/mojoshader_compiler.c index 9141345a..4e992f00 100644 --- a/mojoshader_compiler.c +++ b/mojoshader_compiler.c @@ -59,7 +59,6 @@ typedef enum ASTNodeType AST_OP_START_RANGE_BINARY, AST_OP_DEREF_ARRAY, - AST_OP_CALLFUNC, AST_OP_DEREF_STRUCT, AST_OP_COMMA, AST_OP_MULTIPLY, @@ -106,6 +105,7 @@ typedef enum ASTNodeType AST_OP_END_RANGE_DATA, AST_OP_START_RANGE_MISC, + AST_OP_CALLFUNC, AST_OP_CONSTRUCTOR, AST_OP_CAST, AST_OP_END_RANGE_MISC, @@ -148,6 +148,7 @@ typedef enum ASTNodeType AST_STRUCT_DECLARATION, AST_STRUCT_MEMBER, AST_SWITCH_CASE, + AST_ARGUMENTS, AST_MISC_END_RANGE, AST_END_RANGE @@ -215,6 +216,13 @@ typedef struct ASTGeneric typedef ASTGeneric Expression; +typedef struct Arguments +{ + ASTNode ast; // Always AST_ARGUMENTS + Expression *argument; + struct Arguments *next; +} Arguments; + typedef struct ExpressionUnary { ASTNode ast; @@ -270,9 +278,16 @@ typedef struct ExpressionConstructor { ASTNode ast; // Always AST_OP_CONSTRUCTOR const char *datatype; - Expression *args; + Arguments *args; } ExpressionConstructor; +typedef struct ExpressionCallFunction +{ + ASTNode ast; // Always AST_OP_CALLFUNC + Expression *identifier; + Arguments *args; +} ExpressionCallFunction; + typedef struct ExpressionCast { ASTNode ast; // Always AST_OP_CAST @@ -736,8 +751,17 @@ static void destroy_symbolmap(Context *ctx, SymbolMap *map) static void delete_compilation_unit(Context *ctx, CompilationUnit *unit); static void delete_statement(Context *ctx, Statement *stmt); +static Expression *new_callfunc_expr(Context *ctx, Expression *identifier, + Arguments *args) +{ + NEW_AST_NODE(retval, ExpressionCallFunction, AST_OP_CALLFUNC); + retval->identifier = identifier; + retval->args = args; + return (Expression *) retval; +} // new_callfunc_expr + static Expression *new_constructor_expr(Context *ctx, const char *datatype, - Expression *args) + Arguments *args) { NEW_AST_NODE(retval, ExpressionConstructor, AST_OP_CONSTRUCTOR); retval->datatype = datatype; @@ -820,6 +844,8 @@ static Expression *new_literal_boolean_expr(Context *ctx, const int value) return (Expression *) retval; } // new_literal_boolean_expr +static void delete_arguments(Context *ctx, Arguments *args); + static void delete_expr(Context *ctx, Expression *expr) { DELETE_AST_NODE(expr); @@ -847,7 +873,12 @@ static void delete_expr(Context *ctx, Expression *expr) } // else if else if (expr->ast.type == AST_OP_CONSTRUCTOR) { - delete_expr(ctx, ((ExpressionConstructor *) expr)->args); + delete_arguments(ctx, ((ExpressionConstructor *) expr)->args); + } // else if + else if (expr->ast.type == AST_OP_CALLFUNC) + { + delete_expr(ctx, ((ExpressionCallFunction *) expr)->identifier); + delete_arguments(ctx, ((ExpressionCallFunction *) expr)->args); } // else if // rest of operators don't have extra data to free. @@ -855,6 +886,22 @@ static void delete_expr(Context *ctx, Expression *expr) Free(ctx, expr); } // delete_expr +static Arguments *new_argument(Context *ctx, Expression *argument) +{ + NEW_AST_NODE(retval, Arguments, AST_ARGUMENTS); + retval->argument = argument; + retval->next = NULL; + return retval; +} // new_argument + +static void delete_arguments(Context *ctx, Arguments *args) +{ + DELETE_AST_NODE(args); + delete_arguments(ctx, args->next); + delete_expr(ctx, args->argument); + Free(ctx, args); +} // delete_arguments + static FunctionParameters *new_function_param(Context *ctx, const InputModifier inputmod, const char *datatype, @@ -1553,13 +1600,6 @@ static void print_ast(const int substmt, void *ast) printf("]"); break; - case AST_OP_CALLFUNC: - print_ast(0, ((ExpressionBinary *) ast)->left); - printf("("); - print_ast(0, ((ExpressionBinary *) ast)->right); - printf(")"); - break; - case AST_OP_DEREF_STRUCT: print_ast(0, ((ExpressionBinary *) ast)->left); printf("."); @@ -1781,6 +1821,22 @@ static void print_ast(const int substmt, void *ast) printf("%s", ((ExpressionBooleanLiteral *) ast)->value ? "true" : "false"); break; + case AST_ARGUMENTS: + print_ast(0, ((Arguments *) ast)->argument); + if (((Arguments *) ast)->next != NULL) + { + printf(", "); + print_ast(0, ((Arguments *) ast)->next); + } // if + break; + + case AST_OP_CALLFUNC: + print_ast(0, ((ExpressionCallFunction *) ast)->identifier); + printf("("); + print_ast(0, ((ExpressionCallFunction *) ast)->args); + printf(")"); + break; + case AST_OP_CONSTRUCTOR: printf("%s(", ((ExpressionConstructor *) ast)->datatype); print_ast(0, ((ExpressionConstructor *) ast)->args); diff --git a/mojoshader_parser_hlsl.lemon b/mojoshader_parser_hlsl.lemon index 1d974757..93a7adb0 100644 --- a/mojoshader_parser_hlsl.lemon +++ b/mojoshader_parser_hlsl.lemon @@ -468,17 +468,21 @@ primary_expr(A) ::= LPAREN expression(B) RPAREN. { A = B; } %destructor postfix_expr { delete_expr(ctx, $$); } postfix_expr(A) ::= primary_expr(B). { A = B; } postfix_expr(A) ::= postfix_expr(B) LBRACKET expression(C) RBRACKET. { A = new_binary_expr(ctx, AST_OP_DEREF_ARRAY, B, C); } -postfix_expr(A) ::= postfix_expr(B) LPAREN RPAREN. { A = new_binary_expr(ctx, AST_OP_CALLFUNC, B, NULL); } -postfix_expr(A) ::= postfix_expr(B) LPAREN argument_expr_list(C) RPAREN. { A = new_binary_expr(ctx, AST_OP_CALLFUNC, B, C); } -postfix_expr(A) ::= datatype(B) LPAREN argument_expr_list(C) RPAREN. { A = new_constructor_expr(ctx, B, C); } // HLSL constructor +postfix_expr(A) ::= postfix_expr(B) arguments(C). { A = new_callfunc_expr(ctx, B, C); } +postfix_expr(A) ::= datatype(B) arguments(C). { A = new_constructor_expr(ctx, B, C); } // HLSL constructor postfix_expr(A) ::= postfix_expr(B) DOT IDENTIFIER(C). { A = new_binary_expr(ctx, AST_OP_DEREF_STRUCT, B, new_identifier_expr(ctx, C.string)); } postfix_expr(A) ::= postfix_expr(B) PLUSPLUS. { A = new_unary_expr(ctx, AST_OP_POSTINCREMENT, B); } postfix_expr(A) ::= postfix_expr(B) MINUSMINUS. { A = new_unary_expr(ctx, AST_OP_POSTDECREMENT, B); } -%type argument_expr_list { Expression * } -%destructor argument_expr_list { delete_expr(ctx, $$); } -argument_expr_list(A) ::= assignment_expr(B). { A = B; } -argument_expr_list(A) ::= argument_expr_list(B) COMMA assignment_expr(C). { A = new_binary_expr(ctx, AST_OP_COMMA, B, C); } +%type arguments { Arguments * } +%destructor arguments { delete_arguments(ctx, $$); } +arguments(A) ::= LPAREN RPAREN. { A = NULL; } +arguments(A) ::= LPAREN argument_list(B) RPAREN. { REVERSE_LINKED_LIST(Arguments, B); A = B; } + +%type argument_list { Arguments * } +%destructor argument_list { delete_arguments(ctx, $$); } +argument_list(A) ::= assignment_expr(B). { A = new_argument(ctx, B); } +argument_list(A) ::= argument_list(B) COMMA assignment_expr(C). { A = new_argument(ctx, C); A->next = B; } %type unary_expr { Expression * } %destructor unary_expr { delete_expr(ctx, $$); }