Exemple #1
0
/**
 * CTRParserExpression
 *
 * Generates a set of nodes to represent an expression.
 */
ctr_tnode* ctr_cparse_expr(int mode) {
	ctr_tnode* r;
	ctr_tnode* e;
	int t2;
	ctr_tlistitem* nodes;
	ctr_tlistitem* rli;
	if (ctr_mode_debug) printf("Parsing expression (mode: %d).\n", mode);	
	r = ctr_cparse_receiver();
	t2 = ctr_clex_tok();
	if (ctr_mode_debug) printf("First token after receiver = %d \n", t2);
	ctr_clex_putback();
	if (r->type == CTR_AST_NODE_REFERENCE && t2 == CTR_TOKEN_ASSIGNMENT) {
		e = ctr_cparse_assignment(r);
	} else if (t2 != CTR_TOKEN_DOT && t2 != CTR_TOKEN_PARCLOSE && t2 != CTR_TOKEN_CHAIN) {
		e = CTR_PARSER_CREATE_NODE();
		e->type = CTR_AST_NODE_EXPRMESSAGE;
		nodes = ctr_cparse_messages(r, mode);
		if (nodes == NULL) {
			int t = ctr_clex_tok();
			ctr_clex_putback();
			if (ctr_mode_debug) printf("No messages, return. Next token: %d.\n", t);
			return r; /* no messages, then just return receiver (might be in case of argument). */
		}
		rli = CTR_PARSER_CREATE_LISTITEM();
		rli->node = r;
		rli->next = nodes;
		e->nodes = rli;
	} else {
		if (ctr_mode_debug) printf("Returning receiver. \n");
		return r;
	}
	return e;
}
Exemple #2
0
/**
 * CTRParserReference
 *
 * Generates the nodes to respresent a variable or property.
 */
ctr_tnode* ctr_cparse_ref() {
	ctr_tnode* r;
	char* tmp;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_REFERENCE;
	r->vlen = ctr_clex_tok_value_length();
	tmp = ctr_clex_tok_value();
	if (strncmp("my", tmp, 2)==0 && r->vlen == 2) {
		int t = ctr_clex_tok();
		if (t != CTR_TOKEN_REF) {
			printf("'My' should always be followed by property name!\n");
			exit(1);
		}
		tmp = ctr_clex_tok_value();
		r->modifier = 1;
		r->vlen = ctr_clex_tok_value_length();
	}
	if (strncmp("var", tmp, 3)==0 && r->vlen == 3) {
		int t = ctr_clex_tok();
		if (t != CTR_TOKEN_REF) {
			printf("'var' should always be followed by property name!\n");
			exit(1);
		}
		tmp = ctr_clex_tok_value();
		r->modifier = 2;
		r->vlen = ctr_clex_tok_value_length();
	}
	r->value = ctr_malloc(r->vlen, 0);
	memcpy(r->value, tmp, r->vlen);
	return r;
}
Exemple #3
0
/**
 * CTRParserStatement
 *
 * Generates a set of nodes representing a statement.
 */
ctr_tlistitem *
ctr_cparse_statement ()
{
  ctr_tlistitem *li = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  int t = ctr_clex_tok ();
  ctr_clex_putback ();
  if (t == CTR_TOKEN_FIN)
    {
      li->node = ctr_cparse_fin ();
      return li;
    }
  else if (t == CTR_TOKEN_RET)
    {
      li->node = ctr_cparse_ret ();
    }
  else
    {
      li->node = ctr_cparse_expr (0);
    }
  t = ctr_clex_tok ();
  if (t != CTR_TOKEN_DOT)
    {
      ctr_cparse_emit_error_unexpected (t, "Expected a dot (.).\n");
      li->node = ctr_cparse_fin ();
    }
  return li;
}
Exemple #4
0
/**
 * Translates a program from one human language to another.
 */
void ctr_translate_program(char* prg, char* programPath) {
	ctr_dict* dictionary;
	int t;
	char* p;
	dictionary = ctr_translate_load_dictionary();
	ctr_clex_set_ignore_modes(1);
	ctr_clex_load(prg);
	t = ctr_clex_tok();
	p = prg;
	while ( 1 ) {
		if ( t == CTR_TOKEN_FIN ) {
			ctr_translate_fin(p);
			break;
		}
		else if ( t == CTR_TOKEN_QUOTE ) {
			p = ctr_translate_string(p, dictionary);
		} 
		else if ( t == CTR_TOKEN_REF || t == CTR_TOKEN_BOOLEANYES || t == CTR_TOKEN_BOOLEANNO || t == CTR_TOKEN_NIL ) {
			p = ctr_translate_ref(p,dictionary);
		}
		else {
			p = ctr_translate_rest(p);
		}
		t = ctr_clex_tok();
	}
	ctr_translate_unload_dictionary( dictionary );
}
Exemple #5
0
/**
 * CTRParserMessages
 *
 * Manages the creation of nodes to send a message, uses CTRParserMessage
 * to create the actual nodes.
 */
ctr_tlistitem *
ctr_cparse_messages (ctr_tnode * r, int mode)
{
  int t = ctr_clex_tok ();
  ctr_tlistitem *pli = NULL;
  ctr_tlistitem *li = NULL;
  ctr_tlistitem *fli = NULL;
  int first = 1;
  ctr_tnode *node = NULL;
  /* explicit chaining (,) only allowed for keyword message: Console write: 3 factorial, write: 3 factorial is not possible otherwise. */
  while ((t == CTR_TOKEN_REF || (t == CTR_TOKEN_CHAIN && node && node->type == CTR_AST_NODE_KWMESSAGE)))
    {
      if (t == CTR_TOKEN_CHAIN)
	{
	  t = ctr_clex_tok ();
	  if (t != CTR_TOKEN_REF)
	    {
	      ctr_cparse_emit_error_unexpected (t, "Expected message.\n");
	    }
	}
      li = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
      ctr_clex_putback ();
      node = ctr_cparse_message (mode);
      if (node->type == -1)
	{
	  if (first)
	    {
	      return NULL;
	    }
	  ctr_clex_tok ();
	  break;
	}
      li->node = node;
      if (first)
	{
	  first = 0;
	  pli = li;
	  fli = li;
	}
      else
	{
	  pli->next = li;
	  pli = li;
	}
      t = ctr_clex_tok ();
    }
  ctr_clex_putback ();
  return fli;
}
Exemple #6
0
/**
 * CTRParserReference
 *
 * Generates the nodes to respresent a variable or property.
 */
ctr_tnode *
ctr_cparse_ref ()
{
  ctr_tnode *r;
  char *tmp;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_REFERENCE;
  r->vlen = ctr_clex_tok_value_length ();
  tmp = ctr_clex_tok_value ();
  if (all_plains_private)
    r->modifier = (do_compare_locals) ? (ctr_paramlist_has_name (tmp, r->vlen) ? 0 : 3) : 3;
  if (strncmp (ctr_clex_keyword_my, tmp, ctr_clex_keyword_my_len) == 0 && r->vlen == ctr_clex_keyword_my_len)
    {
      int t = ctr_clex_tok ();
      if (t != CTR_TOKEN_REF)
	{
	  ctr_cparse_emit_error_unexpected (t, "'My' should always be followed by a property name!\n");
	}
      tmp = ctr_clex_tok_value ();
      r->modifier = 1;
      r->vlen = ctr_clex_tok_value_length ();
    }
  if (strncmp (ctr_clex_keyword_var, tmp, ctr_clex_keyword_var_len) == 0 && r->vlen == ctr_clex_keyword_var_len)
    {
      int t = ctr_clex_tok ();
      if (t != CTR_TOKEN_REF)
	{
	  ctr_cparse_emit_error_unexpected (t, "Keyword 'var' should always be followed by property name!\n");
	}
      tmp = ctr_clex_tok_value ();
      r->modifier = 2;
      r->vlen = ctr_clex_tok_value_length ();
    }
  if (strncmp (ctr_clex_keyword_const, tmp, ctr_clex_keyword_const_len) == 0 && r->vlen == ctr_clex_keyword_const_len)
    {
      int t = ctr_clex_tok ();
      if (t != CTR_TOKEN_REF)
	{
	  ctr_cparse_emit_error_unexpected (t, "'const' must always be followed by a single reference/property\n");
	}
      tmp = ctr_clex_tok_value ();
      r->modifier = 3;
      r->vlen = ctr_clex_tok_value_length ();
    }
  r->value = ctr_heap_allocate_tracked (r->vlen);
  memcpy (r->value, tmp, r->vlen);
  return r;
}
Exemple #7
0
/**
 * CTRParserFin
 *
 * Generates a node to represent the end of a program.
 */
ctr_tnode* ctr_cparse_fin() {
	ctr_tnode* f;
	ctr_clex_tok();
	f = CTR_PARSER_CREATE_NODE();
	f->type = CTR_AST_NODE_ENDOFPROGRAM;
	return f;
}
Exemple #8
0
/**
 * CTRParserReceiver
 *
 * Generates a node to represent a receiver (of a message).
 */
ctr_tnode* ctr_cparse_receiver() {
	int t;
	if (ctr_mode_debug) printf("Parsing receiver.\n");
	t = ctr_clex_tok();
	ctr_clex_putback();
	switch(t){
		case CTR_TOKEN_NIL:
			return ctr_cparse_nil();
		case CTR_TOKEN_BOOLEANYES:
			return ctr_cparse_true();
		case CTR_TOKEN_BOOLEANNO:
			return ctr_cparse_false();
		case CTR_TOKEN_NUMBER:
			return ctr_cparse_number();
		case CTR_TOKEN_QUOTE:
			return ctr_cparse_string();
		case CTR_TOKEN_REF:
			return ctr_cparse_ref();
		case CTR_TOKEN_BLOCKOPEN:
			return ctr_cparse_block();
		case CTR_TOKEN_PAROPEN:
			return ctr_cparse_popen();
		default:
			printf("Error, unexpected token: %d.\n", t);
			exit(1);
	}
}
Exemple #9
0
/**
 * CTRParserString
 *
 * Generates a node to represent a string.
 */
ctr_tnode* ctr_cparse_string() {
	ctr_tnode* r;
	char* n;
	ctr_size vlen;
	if (ctr_mode_debug) printf("Parsing STRING. \n");
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRSTRING;
	n = ctr_clex_readstr();
	vlen = ctr_clex_tok_value_length();
	r->value = ctr_malloc(sizeof(char) * vlen, 0);
	memcpy(r->value, n, vlen);
	r->vlen = vlen;
	ctr_clex_tok(); /* eat trailing quote. */
	return r;
}
Exemple #10
0
/**
 * CTRParserMessages
 * 
 * Manages the creation of nodes to send a message, uses CTRParserMessage
 * to create the actual nodes.
 */
ctr_tlistitem* ctr_cparse_messages(ctr_tnode* r, int mode) {
	int t = ctr_clex_tok();
	ctr_tlistitem* pli;
	ctr_tlistitem* li;
	ctr_tlistitem* fli;
	int first = 1;
	ctr_tnode* node;
	if (ctr_mode_debug) printf("Parsing messages.\n");
	/* explicit chaining (,) only allowed for keyword message: Console write: 3 factorial, write: 3 factorial is not possible otherwise. */
	while ((t == CTR_TOKEN_REF || (t == CTR_TOKEN_CHAIN && node && node->type == CTR_AST_NODE_KWMESSAGE))) {
		if (t == CTR_TOKEN_CHAIN) {
			t = ctr_clex_tok();
			if (t != CTR_TOKEN_REF) {
				printf("Expected message.\n");
				exit(1);
			}
		}
		li = CTR_PARSER_CREATE_LISTITEM();
		if (ctr_mode_debug) printf("Next message...\n");
		ctr_clex_putback();
		node = ctr_cparse_message(mode);
		if (node->type == -1) {
			if (ctr_mode_debug) printf("Ending message sequence.\n");
			if (first) {
				if (ctr_mode_debug) printf("First so return NULL.\n");
				return NULL;
			}
			ctr_clex_tok();
			break;
		}
		li->node = node;
		if (first) {
			first = 0;
			pli = li;
			fli = li;
		} else {
			pli->next = li;
			pli = li;
		}
		t = ctr_clex_tok();
		if (ctr_mode_debug) printf("Next token in message line is: %d \n",t);
	}
	if (ctr_mode_debug) printf("Putting back token... \n");
	ctr_clex_putback();
	return fli;
}
Exemple #11
0
/**
 * CTRParserSymbol
 *
 * Generates a symbol or pulls it from the static symbol list.
 */
ctr_tnode *
ctr_cparse_symbol ()
{
  ctr_tnode *r;
  ctr_tlistitem *li;
  r = ctr_cparse_create_node (CTR_AST_NODE);
  int t = ctr_clex_tok ();
  if (t != CTR_TOKEN_SYMBOL)
    return NULL;
  ctr_clex_tok ();
  r->type = CTR_AST_NODE_SYMBOL;
  li = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  ctr_size vlen = ctr_clex_tok_value_length ();
  r->value = (char *) ctr_get_or_create_symbol_table_entry (ctr_clex_tok_value (), vlen);
  r->vlen = -1;			//sig
  return r;
}
Exemple #12
0
/**
 * CTRParserString
 *
 * Generates a node to represent a string.
 */
ctr_tnode *
ctr_cparse_string ()
{
  ctr_tnode *r;
  char *n;
  ctr_size vlen;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_LTRSTRING;
  n = ctr_clex_readstr ();
  vlen = ctr_clex_tok_value_length ();
  r->value = ctr_heap_allocate_tracked (sizeof (char) * vlen);
  memcpy (r->value, n, vlen);
  r->vlen = vlen;
  ctr_clex_tok ();		/* eat trailing quote. */
  return r;
}
Exemple #13
0
/**
 * CTRParserNil
 *
 * Generates a node to represent Nil
 */
ctr_tnode* ctr_cparse_nil() {
	ctr_tnode* r;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRNIL;
	r->value = "Nil";
	r->vlen = 3;
	return r;
}
Exemple #14
0
/**
 * CTRParserBooleanTrue
 *
 * Generates a node to represent a boolean True.
 */
ctr_tnode* ctr_cparse_true() {
	ctr_tnode* r;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRBOOLTRUE;
	ASSIGN_STRING(r, value,"True",4);	
	r->vlen = 4;
	return r;
}
Exemple #15
0
/**
 * CTRParserBooleanFalse
 *
 * Generates a node to represent a boolean False.
 */
ctr_tnode* ctr_cparse_false() {
	ctr_tnode* r;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRBOOLFALSE;
	ASSIGN_STRING(r, value, "False", 5);
	r->vlen = 5;
	return r;
}
Exemple #16
0
/**
 * CTRParserPOpen
 *
 * Generates a set of nested nodes.
 */
ctr_tnode* ctr_cparse_popen() {
	ctr_tnode* r;
	ctr_tlistitem* li;
	int t;
	ctr_clex_tok();
	if (ctr_mode_debug) printf("Parsing paren open (.\n");
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_NESTED;
	li = CTR_PARSER_CREATE_LISTITEM();
	r->nodes = li;
	li->node = ctr_cparse_expr(0);
	t = ctr_clex_tok();
	if (t != CTR_TOKEN_PARCLOSE) {
		printf("Error, expected ). \n");
		exit(1);
	}
	return r;
}
Exemple #17
0
/**
 * CTRParserFin
 *
 * Generates a node to represent the end of a program.
 */
ctr_tnode *
ctr_cparse_fin ()
{
  ctr_tnode *f;
  ctr_clex_tok ();
  f = ctr_cparse_create_node (CTR_AST_NODE);
  f->type = CTR_AST_NODE_ENDOFPROGRAM;
  return f;
}
Exemple #18
0
/**
 * CTRParserPOpen
 *
 * Generates a set of nested nodes.
 */
ctr_tnode *
ctr_cparse_popen ()
{
  ctr_tnode *r;
  ctr_tlistitem *li;
  int t;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_NESTED;
  li = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  r->nodes = li;
  li->node = ctr_cparse_expr (0);
  t = ctr_clex_tok ();
  if (t != CTR_TOKEN_PARCLOSE)
    {
      ctr_cparse_emit_error_unexpected (t, "Expected ).\n");
    }
  return r;
}
Exemple #19
0
/**
 * CTRParserNil
 *
 * Generates a node to represent Nil
 */
ctr_tnode *
ctr_cparse_nil ()
{
  ctr_tnode *r;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_LTRNIL;
  r->value = "Nil";
  r->vlen = 3;
  return r;
}
Exemple #20
0
/**
 * CTRParserReturn
 *
 * Generates a node to represent a return from a block of code.
 */
ctr_tnode* ctr_cparse_ret() {
	ctr_tlistitem* li;
	ctr_tnode* r;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_RETURNFROMBLOCK;
	li = CTR_PARSER_CREATE_LISTITEM();
	r->nodes = li;
	li->node = ctr_cparse_expr(0);
	return r;
}
Exemple #21
0
/**
 * CTRParserStatement
 *
 * Generates a set of nodes representing a statement.
 */
ctr_tlistitem* ctr_cparse_statement() {
	ctr_tlistitem* li = CTR_PARSER_CREATE_LISTITEM();
	int t = ctr_clex_tok();
	if (ctr_mode_debug) printf("Parsing next statement of program, token = %d (%s).\n", t, ctr_clex_tok_value());
	ctr_clex_putback();
	if (t == CTR_TOKEN_FIN) {
		li->node = ctr_cparse_fin();
		return li;
	} else if (t == CTR_TOKEN_RET) {
		li->node = ctr_cparse_ret();
	} else {
		li->node = ctr_cparse_expr(0);
	}
	t = ctr_clex_tok();
	if (t != CTR_TOKEN_DOT) {
		printf("Expected . but got: %d.\n", t);
		exit(1);
	}
	return li;
}
Exemple #22
0
/**
 * CTRParserBooleanTrue
 *
 * Generates a node to represent a boolean True.
 */
ctr_tnode *
ctr_cparse_true ()
{
  ctr_tnode *r;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_LTRBOOLTRUE;
  r->value = ctr_heap_allocate_tracked (sizeof (char) * 4);
  memcpy (r->value, "True", 4);
  r->vlen = 4;
  return r;
}
Exemple #23
0
/**
 * CTRParserBooleanFalse
 *
 * Generates a node to represent a boolean False.
 */
ctr_tnode *
ctr_cparse_false ()
{
  ctr_tnode *r;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_LTRBOOLFALSE;
  r->value = ctr_heap_allocate_tracked (sizeof (char) * 5);
  memcpy (r->value, "False", 5);
  r->vlen = 5;
  return r;
}
Exemple #24
0
/**
 * CTRParserReturn
 *
 * Generates a node to represent a return from a block of code.
 */
ctr_tnode *
ctr_cparse_ret ()
{
  ctr_tlistitem *li;
  ctr_tnode *r;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_RETURNFROMBLOCK;
  li = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  r->nodes = li;
  li->node = ctr_cparse_expr (0);
  return r;
}
Exemple #25
0
ctr_tnode* ctr_cparse_number() {
	char* n;
	ctr_tnode* r;
	long l;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRNUM;
	n = ctr_clex_tok_value();
	l = ctr_clex_tok_value_length();
	r->value = ctr_malloc(sizeof(char) * l, 0);
	memcpy(r->value, n, l);
	r->vlen = l;
	return r;
}
Exemple #26
0
/**
 * CTRParserAssignment
 *
 * Generates a node to represent an assignment.
 */
ctr_tnode* ctr_cparse_assignment(ctr_tnode* r) {
	ctr_tnode* a;
	ctr_tlistitem* li;
	ctr_tlistitem* liAssignExpr;
	ctr_clex_tok();
	a = CTR_PARSER_CREATE_NODE();
	li = CTR_PARSER_CREATE_LISTITEM();
	liAssignExpr = CTR_PARSER_CREATE_LISTITEM();
	a->type = CTR_AST_NODE_EXPRASSIGNMENT;
	a->nodes = li;
	li->node = r;
	liAssignExpr->node =   ctr_cparse_expr(0);  
	li->next = liAssignExpr;
	return a;
}
Exemple #27
0
/**
 * CTRParserReceiver
 *
 * Generates a node to represent a receiver (of a message).
 */
ctr_tnode* ctr_cparse_receiver() {
	int t;
	if (ctr_mode_debug) printf("Parsing receiver.\n");
	t = ctr_clex_tok();
	ctr_clex_putback();
	if (t == CTR_TOKEN_NIL) return ctr_cparse_nil();
	if (t == CTR_TOKEN_BOOLEANYES) return ctr_cparse_true();
	if (t == CTR_TOKEN_BOOLEANNO) return ctr_cparse_false();
	if (t == CTR_TOKEN_NUMBER) return ctr_cparse_number();
	if (t == CTR_TOKEN_QUOTE) return ctr_cparse_string();
	if (t == CTR_TOKEN_REF) return ctr_cparse_ref();
	if (t == CTR_TOKEN_BLOCKOPEN) return ctr_cparse_block();
	if (t == CTR_TOKEN_PAROPEN) return ctr_cparse_popen();
	printf("Error, unexpected token: %d.\n", t);
	exit(1);
}
Exemple #28
0
ctr_tnode *
ctr_cparse_number ()
{
  char *n;
  ctr_tnode *r;
  long l;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_LTRNUM;
  n = ctr_clex_tok_value ();
  l = ctr_clex_tok_value_length ();
  r->value = ctr_heap_allocate_tracked (sizeof (char) * l);
  memcpy (r->value, n, l);
  r->vlen = l;
  return r;
}
Exemple #29
0
/**
 * CTRParserAssignment
 *
 * Generates a node to represent an assignment.
 */
ctr_tnode *
ctr_cparse_assignment (ctr_tnode * r)
{
  ctr_tnode *a;
  ctr_tlistitem *li;
  ctr_tlistitem *liAssignExpr;
  ctr_clex_tok ();
  a = ctr_cparse_create_node (CTR_AST_NODE);
  li = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  liAssignExpr = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  a->type = CTR_AST_NODE_EXPRASSIGNMENT;
  a->nodes = li;
  li->node = r;
  liAssignExpr->node = ctr_cparse_expr (0);
  li->next = liAssignExpr;
  return a;
}
Exemple #30
0
/**
 * CTRParserReceiver
 *
 * Generates a node to represent a receiver (of a message).
 */
ctr_tnode *
ctr_cparse_receiver ()
{
  int t;
  t = ctr_clex_tok ();
  ctr_clex_putback ();
  switch (t)
    {
    case CTR_TOKEN_NIL:
      return ctr_cparse_nil ();
    case CTR_TOKEN_BOOLEANYES:
      return ctr_cparse_true ();
    case CTR_TOKEN_BOOLEANNO:
      return ctr_cparse_false ();
    case CTR_TOKEN_NUMBER:
      return ctr_cparse_number ();
    case CTR_TOKEN_QUOTE:
      return ctr_cparse_string ();
    case CTR_TOKEN_REF:
      return ctr_cparse_ref ();
    case CTR_TOKEN_BLOCKOPEN:
      return ctr_cparse_block ();
    case CTR_TOKEN_BLOCKOPEN_MAP:
      {
	ctr_tnode *t = ctr_cparse_block_capture ();
	t->lexical = 1;
	t->nodes->next->node->lexical = 1;
	return t;
      }
    case CTR_TOKEN_PAROPEN:
      return ctr_cparse_popen ();
    case CTR_TOKEN_TUPOPEN:
      return ctr_cparse_tuple ();
    case CTR_TOKEN_SYMBOL:
      return ctr_cparse_symbol ();
    default:
      /* This function always exits, so return a dummy value. */
      ctr_cparse_emit_error_unexpected (t, "Expected a message recipient.\n");
      return NULL;
    }
}