From 72f35ba765aa8aad82421b26b4f61377ae0aee9b Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Mon, 31 Aug 2020 21:29:19 +0200 Subject: parameter list as double linked list (work in progress) --- ecomp-c/ec.c | 78 ++++++++++++++++++++++++++++++++++++++++----------------- ecomp-c/test1.e | 14 ++++++----- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c index 3c0d0f6..c32865a 100644 --- a/ecomp-c/ec.c +++ b/ecomp-c/ec.c @@ -866,7 +866,7 @@ typedef enum ExpressionNodeType { typedef struct ExpressionNode { ExpressionNodeType type; S_Symbol op; - struct ExpressionNode *left, *right, *next; + struct ExpressionNode *left, *right, *next, *prev; int integer_value; int boolean_value; char character_value; @@ -876,12 +876,18 @@ typedef struct ExpressionNode { Symbol *actual_type; } ExpressionNode; +typedef struct ExpressionNodeList { + ExpressionNode *head; + ExpressionNode *tail; +} ExpressionNodeList; + static ExpressionNode *create_expression_node( void ) { ExpressionNode *node = Allocate( sizeof( ExpressionNode ) ); node->left = NULL; node->right = NULL; node->next = NULL; + node->prev = NULL; node->string_value = NULL; node->intarr_value = NULL; @@ -899,6 +905,7 @@ static void free_expression_node( ExpressionNode *node ) if( node->next != NULL ) { free_expression_node( node->next ); } + /* do not free node->prev! double linked list */ if( node->string_value != NULL ) { free( node->string_value ); } @@ -1582,29 +1589,54 @@ static void parseWhileStatement( Scope *scope ) free( jump_label1 ); } -static ExpressionNode *parseParameterList( Scope *scope ) +static void parseParameterList( Scope *scope, ExpressionNodeList *list ) { - ExpressionNode *head, *tail, *node; - + ExpressionNode *node; +/* + * function insertBefore(List list, Node node, Node newNode) + newNode.next := node + if node.prev == null + newNode.prev := null -- (not always necessary) + list.firstNode := newNode + else + newNode.prev := node.prev + node.prev.next := newNode + node.prev := newNode + +We also need a function to insert a node at the beginning of a possibly empty list: + +function insertBeginning(List list, Node newNode) + if list.firstNode == null + list.firstNode := newNode + list.lastNode := newNode + newNode.prev := null + newNode.next := null + else + insertBefore(list, list.firstNode, newNode) +*/ Expect( S_lparen ); - head = NULL; - tail = NULL; + list->head = NULL; + list->tail = NULL; do { node = parseExpression( scope ); - if( head == NULL && tail == NULL ) { - head = node; - tail = node; + if( list->head == NULL && list->tail == NULL ) { + list->head = node; + list->tail = node; } else { - node->next = head; - head = node; - } + node->next = list->head; + if( list->head->prev == NULL ) { + list->head = node; + } else { + node->prev = list->head->prev; + list->head->prev->next = node; + } + list->head->prev = node; + } if( sym == S_comma ) { sym = getSym( ); } } while( sym != S_rparen ); Expect( S_rparen ); - - return node; } static void parseProcedureCall( Scope *scope ) @@ -1612,7 +1644,8 @@ static void parseProcedureCall( Scope *scope ) Symbol *symbol, *param; int nof_expected_params; int nof_actual_params; - ExpressionNode *head, *node; + ExpressionNode *node; + ExpressionNodeList list; symbol = get_symbol( scope, ident ); @@ -1624,11 +1657,10 @@ static void parseProcedureCall( Scope *scope ) } nof_actual_params = 0; - head = NULL; if( sym == S_lparen ) { - head = parseParameterList( scope ); + parseParameterList( scope, &list ); - node = head; + node = list.head; while( node != NULL ) { nof_actual_params++; node = node->next; @@ -1642,14 +1674,14 @@ static void parseProcedureCall( Scope *scope ) /* check types */ if( nof_expected_params > 0 ) { - node = head; + node = list.tail; param = symbol->param; while( param != NULL ) { if( !is_compatible_type( node->actual_type, param->type ) ) { Abort( "Incompatible parameter type for parameter '%s' in procedure '%s', expecting type '%s', got '%s'", param->name, symbol->name, param->type->name, node->actual_type->name ); } - node = node->next; + node = node->prev; param = param->next; } } @@ -1658,7 +1690,7 @@ static void parseProcedureCall( Scope *scope ) Emit( "; CALL %s", symbol->label ); if( nof_actual_params > 0 ) { Emit( "( " ); - node = head; + node = list.head; while( node != NULL ) { generate_expression_comment( node ); node = node->next; @@ -1669,13 +1701,13 @@ static void parseProcedureCall( Scope *scope ) /* emit assembly to push parameters onto stack and call procedure */ if( nof_actual_params > 0 ) { - node = head; + node = list.head; while( node != NULL ) { emit_expression_code( node, scope ); node = node->next; } - free_expression_node( head ); + free_expression_node( list.head ); } Emit( "call %s\n", symbol->label ); diff --git a/ecomp-c/test1.e b/ecomp-c/test1.e index 0dfad07..907e595 100644 --- a/ecomp-c/test1.e +++ b/ecomp-c/test1.e @@ -32,7 +32,7 @@ var s2 : array 10 of character := "hello"; a1 : array 10 of integer; -procedure B( n : integer, m : integer ); +procedure B( n : integer, m : integer, f : boolean ); procedure A; const @@ -44,16 +44,18 @@ var begin a1[5] := 43; s[0] := 'L'; - B( a1[5], 7 ); + B( a1[5], 7, true ); end -procedure B( n : integer, m : integer ); +procedure B( n : integer, m : integer, f : boolean ); var x : integer; begin - x := n + m; - a1[4] := x; + if( f ) { + x := n + m; + a1[4] := x; + } end begin @@ -98,5 +100,5 @@ begin a1[3] := 42; s2[a1[2]] := 'Z'; A; - B( 1, 2 ); + B( 1, 2, false ); end -- cgit v1.2.3-54-g00ecf