summaryrefslogtreecommitdiff
path: root/ecomp-c/ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecomp-c/ec.c')
-rw-r--r--ecomp-c/ec.c84
1 files changed, 70 insertions, 14 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index f6e1926..2ab0fb1 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -831,7 +831,7 @@ typedef enum ExpressionNodeType {
typedef struct ExpressionNode {
ExpressionNodeType type;
S_Symbol op;
- struct ExpressionNode *left, *right;
+ struct ExpressionNode *left, *right, *next;
int integer_value;
int boolean_value;
char character_value;
@@ -846,6 +846,7 @@ static ExpressionNode *create_expression_node( void )
ExpressionNode *node = Allocate( sizeof( ExpressionNode ) );
node->left = NULL;
node->right = NULL;
+ node->next = NULL;
node->string_value = NULL;
node->intarr_value = NULL;
@@ -860,6 +861,9 @@ static void free_expression_node( ExpressionNode *node )
if( node->right != NULL ) {
free_expression_node( node->right );
}
+ if( node->next != NULL ) {
+ free_expression_node( node->next );
+ }
if( node->string_value != NULL ) {
free( node->string_value );
}
@@ -1543,37 +1547,89 @@ static void parseWhileStatement( Scope *scope )
free( jump_label1 );
}
-static void parseParameterList( Scope *scope )
+static ExpressionNode *parseParameterList( Scope *scope )
{
- ExpressionNode *node;
+ ExpressionNode *head, *tail, *node;
Expect( S_lparen );
- Emit( "( " );
+ head = NULL;
+ tail = NULL;
do {
node = parseExpression( scope );
- generate_expression_comment( node );
+ if( head == NULL && tail == NULL ) {
+ head = node;
+ tail = node;
+ } else {
+ node->next = head;
+ head = node;
+ }
if( sym == S_comma ) {
sym = getSym( );
}
} while( sym != S_rparen );
Expect( S_rparen );
-
- Emit( ")\n" );
-
- emit_expression_code( node, scope );
+
+ return node;
}
static void parseProcedureCall( Scope *scope )
{
- Symbol *symbol;
+ Symbol *symbol, *param;
+ int nof_expected_params;
+ int nof_actual_params;
+ ExpressionNode *head, *node;
symbol = get_symbol( scope, ident );
+
+ nof_expected_params = 0;
+ param = symbol->scope->symbol;
+ while( param != NULL ) {
+ if( param->offset < 0 ) {
+ nof_expected_params++;
+ }
+ param = param->next;
+ }
+
+ nof_actual_params = 0;
+ if( sym == S_lparen ) {
+ head = parseParameterList( scope );
+ node = head;
+ while( node != NULL ) {
+ nof_actual_params++;
+ node = node->next;
+ }
+ }
+
+ /* TODO: check parameter list types, not only cardinality
+ */
+ if( nof_actual_params != nof_expected_params ) {
+ Abort( "procedure '%s' expects %d parameter(s), but %d were given", symbol->name, nof_expected_params, nof_actual_params );
+ }
+
+ /* emit assembly comments */
Emit( "; CALL %s", symbol->label );
- if( sym == S_lparen ) {
- parseParameterList( scope );
- } else {
- Emit( "\n" );
+ if( nof_actual_params > 0 ) {
+ Emit( "( " );
+ node = head;
+ while( node != NULL ) {
+ generate_expression_comment( node );
+ node = node->next;
+ }
+ Emit( ")" );
+ }
+ Emit( "\n" );
+
+ /* emit assembly to push parameters onto stack and call procedure */
+ if( nof_actual_params > 0 ) {
+ node = head;
+ while( node != NULL ) {
+ emit_expression_code( node, scope );
+ node = node->next;
+ }
+
+ free_expression_node( head );
+
}
Emit( "call %s\n", symbol->label );
}