summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-08-31 21:29:19 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-08-31 21:29:19 +0200
commit72f35ba765aa8aad82421b26b4f61377ae0aee9b (patch)
treed1ad437847f21c5c6ad54fa984c0d65a27e68628
parent71e2a4f4926d36a9595aad58b6fa7ef19c2bbfb9 (diff)
downloadcompilertests-72f35ba765aa8aad82421b26b4f61377ae0aee9b.tar.gz
compilertests-72f35ba765aa8aad82421b26b4f61377ae0aee9b.tar.bz2
parameter list as double linked list (work in progress)
-rw-r--r--ecomp-c/ec.c78
-rw-r--r--ecomp-c/test1.e14
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