示例#1
0
文件: parser.c 项目: probonopd/citron
/**
 * 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;
}
示例#2
0
文件: parser.c 项目: adamkao/citrine
/**
 * 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;
}
示例#3
0
文件: parser.c 项目: probonopd/citron
/**
 * 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;
}
示例#4
0
文件: parser.c 项目: adamkao/citrine
/**
 * 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;
}
示例#5
0
文件: parser.c 项目: probonopd/citron
/**
 * 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;
}
示例#6
0
文件: parser.c 项目: adamkao/citrine
/**
 * 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;
}
示例#7
0
文件: parser.c 项目: probonopd/citron
/**
 * 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;
}
示例#8
0
文件: parser.c 项目: adamkao/citrine
/**
 * 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;
}
示例#9
0
文件: parser.c 项目: probonopd/citron
ctr_tnode *
ctr_cparse_expr (int mode)
{
  ctr_tnode *r;
  ctr_tnode *e;
  int t2;
  ctr_tlistitem *nodes;
  ctr_tlistitem *rli;
  struct lexer_state lexer_state;
  ctr_clex_dump_state (&lexer_state);
  r = ctr_cparse_receiver ();
  t2 = ctr_clex_tok ();
  ctr_clex_putback ();

  /* user tries to put colon directly after recipient */
  if (t2 == CTR_TOKEN_COLON)
    {
      /* Parse as if we had a "me" before this */
      ctr_clex_load_state (lexer_state);
      if (ctr_clex_inject_token (CTR_TOKEN_REF, me_s, 2))
	ctr_cparse_emit_error_unexpected (t2, "Recipient cannot be followed by a colon in this state.\n");
      return ctr_cparse_expr (mode);
    }

  if (t2 == CTR_TOKEN_ASSIGNMENT)
    {
      // if ( r->type != CTR_AST_NODE_REFERENCE ) {
      //     ctr_cparse_emit_error_unexpected( t2, "Invalid left-hand assignment.\n" );
      //     exit(1);
      // }
      e = ctr_cparse_assignment (r);
    }
  else if (t2 == CTR_TOKEN_PASSIGNMENT)
    {
      if (r->type != CTR_AST_NODE_REFERENCE)
	{
	  ctr_cparse_emit_error_unexpected (t2, "Invalid left-hand assignment.\n");
	  exit (1);
	}
      r->modifier = 1;		//set private */
      e = ctr_cparse_assignment (r);	//go as usual
      /*r->nodes->node->type = CTR_AST_NODE_LTRSTRING;
         e = ctr_cparse_create_node(CTR_AST_NODE);
         e->type = CTR_AST_NODE_EXPRMESSAGE;
         e->nodes = ctr_heap_allocate(sizeof(ctr_tlistitem));
         e->nodes->node = ctr_cparse_create_node(CTR_AST_NODE);
         e->nodes->node->value = ctr_heap_allocate(sizeof(char)*7); //Reflect
         memcpy(e->nodes->node->value, "Reflect", 7);
         e->nodes->node->vlen = 7;
         e->nodes->node->type = CTR_AST_NODE_REFERENCE;
         e->nodes->next = ctr_heap_allocate(sizeof(ctr_tlistitem));
         e->nodes->next->node = ctr_cparse_create_node(CTR_AST_NODE);
         e->nodes->next->node->type = CTR_AST_NODE_KWMESSAGE;
         e->nodes->next->node->value = ctr_heap_allocate(sizeof(char)*7); //set:to:
         memcpy(e->nodes->next->node->value, "set:to:", 7);
         e->nodes->next->node->vlen = 7;
         e->nodes->next->node->nodes = ctr_heap_allocate(sizeof(ctr_tlistitem));
         e->nodes->next->node->nodes->node = r->nodes->node;
         e->nodes->next->node->nodes->next = ctr_heap_allocate(sizeof(ctr_tlistitem));
         e->nodes->next->node->nodes->next->node = r->nodes->next->node; */
    }
  else if (t2 != CTR_TOKEN_DOT && t2 != CTR_TOKEN_PARCLOSE && (t2 != CTR_TOKEN_CHAIN && mode != CTR_AST_NODE_IMMUTABLE))
    {
      e = ctr_cparse_create_node (CTR_AST_NODE);
      e->type = CTR_AST_NODE_EXPRMESSAGE;
      nodes = ctr_cparse_messages (r, mode == CTR_AST_NODE_IMMUTABLE ? 0 : mode);
      if (nodes == NULL)
	{
	  ctr_clex_tok ();
	  ctr_clex_putback ();
	  return r;		/* no messages, then just return receiver (might be in case of argument). */
	}
      rli = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
      rli->node = r;
      rli->next = nodes;
      e->nodes = rli;
    }
  else
    {
      return r;
    }
  return e;
}
示例#10
0
文件: parser.c 项目: probonopd/citron
ctr_tnode *
ctr_cparse_block_ (int autocap)
{
  ctr_tnode *r;
  ctr_tlistitem *codeBlockPart1;
  ctr_tlistitem *codeBlockPart2;
  ctr_tnode *paramList;
  ctr_tnode *codeList;
  ctr_tlistitem *previousListItem;
  ctr_tlistitem *previousCodeListItem;
  int t;
  int first;
  ctr_clex_tok ();
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_CODEBLOCK;
  codeBlockPart1 = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  r->nodes = codeBlockPart1;
  codeBlockPart2 = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  r->nodes->next = codeBlockPart2;
  paramList = ctr_cparse_create_node (CTR_AST_NODE);
  codeList = ctr_cparse_create_node (CTR_AST_NODE);
  codeBlockPart1->node = paramList;
  codeBlockPart2->node = codeList;
  paramList->type = CTR_AST_NODE_PARAMLIST;
  codeList->type = CTR_AST_NODE_INSTRLIST;
  t = ctr_clex_tok ();
  first = 1;
  while (t == CTR_TOKEN_COLON)
    {
      /* okay we have new parameter, load it */
      t = ctr_clex_tok ();
      ctr_tlistitem *paramListItem = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
      ctr_tnode *paramItem = ctr_cparse_create_node (CTR_AST_NODE);
      long l = ctr_clex_tok_value_length ();
      paramItem->value = ctr_heap_allocate_tracked (sizeof (char) * l);
      memcpy (paramItem->value, ctr_clex_tok_value (), l);
      paramItem->vlen = l;
      paramListItem->node = paramItem;
      if (first)
	{
	  paramList->nodes = paramListItem;
	  previousListItem = paramListItem;
	  first = 0;
	}
      else
	{
	  previousListItem->next = paramListItem;
	  previousListItem = paramListItem;
	}
      t = ctr_clex_tok ();
    }
  first = 1;
  int oldallpl = all_plains_private;
  int olddcl = do_compare_locals;
  do_compare_locals = autocap;
  int oldcalltime = ctr_cparse_calltime_name_id;
  ctr_cparse_calltime_names[++ctr_cparse_calltime_name_id] = paramList;
  all_plains_private = autocap;
  if (ctr_transform_lambda_shorthand)
    {
      ctr_transform_lambda_shorthand = 0;
      ctr_tlistitem *codeListItem;
      ctr_tnode *codeNode;
      ctr_clex_putback ();
      codeListItem = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
      codeNode = ctr_cparse_create_node (CTR_AST_NODE);
      codeNode = ctr_cparse_expr (0);	//parse a single expression
      codeListItem->node = codeNode;
      codeList->nodes = codeListItem;
      previousCodeListItem = codeListItem;
    }
  else
    {
      while ((first || t == CTR_TOKEN_DOT))
	{
	  ctr_tlistitem *codeListItem;
	  ctr_tnode *codeNode;
	  if (first)
	    {
	      ctr_clex_putback ();
	    }
	  t = ctr_clex_tok ();
	  if (t == CTR_TOKEN_BLOCKCLOSE)
	    break;
	  ctr_clex_putback ();
	  codeListItem = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
	  codeNode = ctr_cparse_create_node (CTR_AST_NODE);
	  if (t == CTR_TOKEN_RET)
	    {
	      codeNode = ctr_cparse_ret ();
	    }
	  else
	    {
	      codeNode = ctr_cparse_expr (0);
	    }
	  codeListItem->node = codeNode;
	  if (first)
	    {
	      codeList->nodes = codeListItem;
	      previousCodeListItem = codeListItem;
	      first = 0;
	    }
	  else
	    {
	      previousCodeListItem->next = codeListItem;
	      previousCodeListItem = codeListItem;
	    }
	  t = ctr_clex_tok ();
	  if (t != CTR_TOKEN_DOT && !autocap)
	    {
	      ctr_cparse_emit_error_unexpected (t, "Expected a dot (.).\n");
	    }
	}
    }
  all_plains_private = oldallpl;
  do_compare_locals = olddcl;
  ctr_cparse_calltime_name_id = oldcalltime;
  r->modifier = /*CTR_MODIFIER_AUTOCAPTURE */ autocap == 1;
  return r;
}
示例#11
0
文件: parser.c 项目: probonopd/citron
/**
 * CTRParserTuple
 *
 * Generates a node to represent an immutable array (tuple)
 */
ctr_tnode *
ctr_cparse_tuple ()
{
  ctr_tnode *r;
  ctr_tlistitem *codeBlockPart1;
  ctr_tnode *paramList;
  ctr_tlistitem *previousListItem;
  int t;
  ctr_clex_tok ();		//eat the [
  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_IMMUTABLE;
  codeBlockPart1 = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  r->nodes = codeBlockPart1;
  paramList = ctr_cparse_create_node (CTR_AST_NODE);
  codeBlockPart1->node = paramList;
  paramList->type = CTR_AST_NODE_NESTED;
  t = ctr_clex_tok ();
  ctr_clex_putback ();
  if (t == CTR_TOKEN_TUPCLOSE)
    {
      ctr_clex_tok ();		//eat the ending ]
      return r;
    }
  ctr_tlistitem *paramListItem = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  paramList->nodes = paramListItem;
  paramListItem->node = ctr_cparse_expr (0);
  previousListItem = paramListItem;

  int restore_id = ctr_clex_save_state ();	//save lexer state
  if (restore_id == -1)
    {
      ctr_cparse_emit_error_unexpected (0, "Lexer stack overflow");
      return NULL;
    }
  //try for a list comprehension: expect ,,
  t = ctr_clex_tok ();
  if (t != CTR_TOKEN_CHAIN && t != CTR_TOKEN_TUPCLOSE)
    {				//common element
      ctr_cparse_emit_error_unexpected (t, "Expected a ',' or a ']'");
      return r;
    }
  if (t == CTR_TOKEN_TUPCLOSE)
    {
      return r;
    }
  t = ctr_clex_tok ();
  if (t == CTR_TOKEN_CHAIN)
    {				//list comp
      return ctr_cparse_list_comp (r->nodes->node);
    }
  ctr_clex_restore_state (restore_id);	//restore before checking for listcomp

  while ((t = ctr_clex_tok ()) == CTR_TOKEN_CHAIN)
    {
      /* okay we have new parameter, load it */
      ctr_tlistitem *paramListItem = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
      paramListItem->node = ctr_cparse_expr (0);
      previousListItem->next = paramListItem;
      previousListItem = paramListItem;
    }
  if (t != CTR_TOKEN_TUPCLOSE)
    ctr_cparse_emit_error_unexpected (t, "Expected ].");
  return r;
}
示例#12
0
文件: parser.c 项目: probonopd/citron
/**
 * CTRParserListComp
 *
 * generates a node to represent a list comprehension
 *
 * @param ctr_tnode * main_expr -- the main expression of the comprehension
 * Lexer state at this point:
 *  [ expression ,, expression* ,, expression* ]
 *                 ^
 */
ctr_tnode *
ctr_cparse_list_comp (ctr_tnode * main_expr)
{
  ctr_tnode *r;
  ctr_tlistitem *part0, *part1, *part2, *prev;

  int t;

  r = ctr_cparse_create_node (CTR_AST_NODE);
  r->type = CTR_AST_NODE_LISTCOMP;

  part0 = ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  part1 = ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
  part2 = ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));

  /*
     r
     |_ part0 -- main expression
     |_ part1 -- generator
     |          |_ gen0
     |          |_ gen1, etc
     |_ part2 -- predicate
     |_ p0
     |_ p1, etc
   */
  r->nodes = part0;
  part0->next = part1;
  part1->next = part2;

  part0->node = main_expr;	//save main expression
  t = ctr_clex_tok ();
  ctr_clex_putback ();
  //[ expression ,,, predicate* ] (skipped generators)
  //               ^
  if (t == CTR_TOKEN_CHAIN)
    {
      ctr_clex_tok ();		//eat the ','
      part1->node = NULL;
      goto parse_predicates;
    }
  //[ expression ,, expression* (,,)? expression* ]
  //                ^
  //parse a series of expressions, separated by CHAIN, put into part1
  ctr_tnode *gen = ctr_heap_allocate_tracked (sizeof (*gen));
  gen->nodes = ctr_heap_allocate_tracked (sizeof (*part1));
  part1->node = gen;
  part1 = gen->nodes;
  part1->node = ctr_cparse_expr (0);
  while ((t = ctr_clex_tok ()) == CTR_TOKEN_CHAIN)
    {
      if (ctr_clex_tok () == CTR_TOKEN_CHAIN)
	{
	  ctr_clex_tok ();
	  break;		//we're going into the predicates now
	}
      ctr_clex_putback ();
      part1->next = ctr_heap_allocate_tracked (sizeof (*part1));
      part1 = part1->next;
      part1->node = ctr_cparse_expr (0);
    }
  ctr_clex_putback ();
parse_predicates:;
  t = ctr_clex_tok ();
  ctr_clex_putback ();
  // [ expression ,, expression* ,, ]
  //                               ^
  if (t == CTR_TOKEN_TUPCLOSE)	//no predicates, so a length-one tuple if it has no gens
    {
      ctr_clex_tok ();		//eat the ']'
      // printf("%s\n", ctr_code);
      if (r->nodes->next->node == NULL)
	{			//didn't have generators
	  //replace with a tuple and move on
	  r->type = CTR_AST_NODE_IMMUTABLE;
	  r->nodes->next = NULL;
	}
      else
	{
	  r->nodes->next->next->node = NULL;
	}
      return r;
    }
  // [ expression ,, expression* ,, expression+ ]
  //                                ^
  //parse a series of expressions, separated by CHAIN, put into part2
  ctr_tnode *pred = ctr_heap_allocate_tracked (sizeof (*pred));
  pred->nodes = ctr_heap_allocate_tracked (sizeof (*part2));
  part2->node = pred;
  part2 = pred->nodes;
  part2->node = ctr_cparse_expr (0);
  while ((t = ctr_clex_tok ()) == CTR_TOKEN_CHAIN)
    {
      part2->next = ctr_heap_allocate_tracked (sizeof (*part1));
      part2 = part2->next;
      part2->node = ctr_cparse_expr (0);
    }
  if (t != CTR_TOKEN_TUPCLOSE)
    {
      //bitch about it
      ctr_cparse_emit_error_unexpected (t, "Expected a ']'");
    }
  return r;
}
示例#13
0
文件: parser.c 项目: probonopd/citron
/**
 * CTRParserMessage
 *
 * Creates the AST nodes for sending a message.
 *
 * - precedence mode 0: no argument (allows processing of unary message, binary message and keyword message)
 * - precedence mode 1: as argument of keyword message (allows processing of unary message and binary message)
 * - precedence mode 2: as argument of binary message (only allows processing of unary message)
 */
ctr_tnode *
ctr_cparse_message (int mode)
{
  long msgpartlen;		/* length of part of message string */
  ctr_tnode *m;
  int t;
  char *s;
  char *msg;
  ctr_tlistitem *li;
  ctr_tlistitem *curlistitem;
  int lookAhead;
  int isBin;
  int first;
  t = ctr_clex_tok ();
  msgpartlen = ctr_clex_tok_value_length ();
  if ((msgpartlen) > 255)
    {
      ctr_cparse_emit_error_unexpected (t, "Message too long\n");
    }
  m = ctr_cparse_create_node (CTR_AST_NODE);
  m->type = -1;
  s = ctr_clex_tok_value ();
  msg = ctr_heap_allocate_tracked (255 * sizeof (char));
  memcpy (msg, s, msgpartlen);
  isBin = ctr_utf8_is_one_cluster (msg, msgpartlen);
  if (mode == 2 && isBin)
    {
      ctr_clex_putback ();
      return m;
    }
  if (isBin)
    {
      m->type = CTR_AST_NODE_BINMESSAGE;
      m->value = msg;
      m->vlen = msgpartlen;
      li = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
      li->node = ctr_cparse_expr (2);
      m->nodes = li;
      return m;
    }
  lookAhead = ctr_clex_tok ();
  ctr_clex_putback ();
  if (lookAhead == CTR_TOKEN_COLON)
    {
      if (mode > 0)
	{
	  ctr_clex_putback ();
	  return m;
	}
      *(msg + msgpartlen) = ':';
      msgpartlen += 1;
      if ((msgpartlen) > 255)
	{
	  ctr_cparse_emit_error_unexpected (t, "Message too long\n");
	}
      m->type = CTR_AST_NODE_KWMESSAGE;
      t = ctr_clex_tok ();
      first = 1;
      while (1)
	{
	  li = (ctr_tlistitem *) ctr_heap_allocate_tracked (sizeof (ctr_tlistitem));
	  li->node = ctr_cparse_expr (1);
	  if (first)
	    {
	      m->nodes = li;
	      curlistitem = m->nodes;
	      first = 0;
	    }
	  else
	    {
	      curlistitem->next = li;
	      curlistitem = li;
	    }
	  t = ctr_clex_tok ();
	  if (t == CTR_TOKEN_DOT)
	    break;
	  if (t == CTR_TOKEN_FIN)
	    break;
	  if (t == CTR_TOKEN_CHAIN)
	    break;
	  if (t == CTR_TOKEN_PARCLOSE)
	    break;
	  if (t == CTR_TOKEN_REF)
	    {
	      long l = ctr_clex_tok_value_length ();
	      if ((msgpartlen + l) > 255)
		{
		  ctr_cparse_emit_error_unexpected (t, "Message too long\n");
		}
	      memcpy ((msg + msgpartlen), ctr_clex_tok_value (), l);
	      msgpartlen = msgpartlen + l;
	      *(msg + msgpartlen) = ':';
	      msgpartlen++;
	      t = ctr_clex_tok ();
	      if (t != CTR_TOKEN_COLON)
		{
		  ctr_cparse_emit_error_unexpected (t, "Expected colon.\n");
		}
	    }
	}
      ctr_clex_putback ();	/* not a colon so put back */
      m->value = msg;
      m->vlen = msgpartlen;
    }
  else
    {
      m->type = CTR_AST_NODE_UNAMESSAGE;
      m->value = msg;
      m->vlen = msgpartlen;
    }
  return m;
}
示例#14
0
文件: parser.c 项目: adamkao/citrine
/**
 * CTRParserBlock
 *
 * Generates a set of AST nodes to represent a block of code.
 */
ctr_tnode* ctr_cparse_block() {
	ctr_tnode* r;
	ctr_tlistitem* codeBlockPart1;
	ctr_tlistitem* codeBlockPart2;
	ctr_tnode* paramList;
	ctr_tnode* codeList;
	ctr_tlistitem* previousListItem;
	ctr_tlistitem* previousCodeListItem;
	int t;
	int first;
	if (ctr_mode_debug) printf("Parsing code block.\n");
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_CODEBLOCK;
	codeBlockPart1 = CTR_PARSER_CREATE_LISTITEM();
	r->nodes = codeBlockPart1;
	codeBlockPart2 = CTR_PARSER_CREATE_LISTITEM();
	r->nodes->next = codeBlockPart2;
	paramList = CTR_PARSER_CREATE_NODE();
	codeList  = CTR_PARSER_CREATE_NODE();	
	codeBlockPart1->node = paramList;
	codeBlockPart2->node = codeList;
	paramList->type = CTR_AST_NODE_PARAMLIST;
	codeList->type = CTR_AST_NODE_INSTRLIST;
	t = ctr_clex_tok();
	first = 1;
	while(t == CTR_TOKEN_REF) {
		ctr_tlistitem* paramListItem = CTR_PARSER_CREATE_LISTITEM();
		ctr_tnode* paramItem = CTR_PARSER_CREATE_NODE();
		long l = ctr_clex_tok_value_length();
		paramItem->value = ctr_malloc(sizeof(char) * l, 0);
		memcpy(paramItem->value, ctr_clex_tok_value(), l);
		paramItem->vlen = l;
		paramListItem->node = paramItem;
		if (first) {
			paramList->nodes = paramListItem;
			previousListItem = paramListItem;
			first = 0;
		} else {
			previousListItem->next = paramListItem;
			previousListItem = paramListItem;
		}
		t = ctr_clex_tok();
	}
	if (t != CTR_TOKEN_BLOCKPIPE) {
		printf("Error expected blockpipe.");
		exit(1);
	}
	t = ctr_clex_tok();
	first = 1;
	while((first || t == CTR_TOKEN_DOT)) {
		ctr_tlistitem* codeListItem;
		ctr_tnode* codeNode;
		if (first) {
			if (ctr_mode_debug) printf("First, so put back\n");
			ctr_clex_putback();
		}
		t = ctr_clex_tok();
		if (t == CTR_TOKEN_BLOCKCLOSE) break;
		ctr_clex_putback();
		codeListItem = CTR_PARSER_CREATE_LISTITEM();
		codeNode = CTR_PARSER_CREATE_NODE();
		if (ctr_mode_debug) printf("--------> %d %s \n", t, ctr_clex_tok_value());
		if (t == CTR_TOKEN_RET) {
			codeNode = ctr_cparse_ret();
		} else {
			codeNode = ctr_cparse_expr(0);
		}
		codeListItem->node = codeNode;
		if (first) {
			codeList->nodes = codeListItem;
			previousCodeListItem = codeListItem;
			first = 0;
		} else {
			previousCodeListItem->next = codeListItem;
			previousCodeListItem = codeListItem;
		}
		t = ctr_clex_tok();
		if (t != CTR_TOKEN_DOT) {
			printf("Expected . but got: %d.\n", t);
			exit(1);
		}
	}
	return r;
}
示例#15
0
文件: parser.c 项目: adamkao/citrine
/**
 * CTRParserMessage
 *
 * Creates the AST nodes for sending a message.
 *
 * - precedence mode 0: no argument (allows processing of unary message, binary message and keyword message)
 * - precedence mode 1: as argument of keyword message (allows processing of unary message and binary message)
 * - precedence mode 2: as argument of binary message (only allows processing of unary message)
 */
ctr_tnode* ctr_cparse_message(int mode) {
	long msgpartlen; /* length of part of message string */
	ctr_tnode* m;
	int t;
	char* s;
	char* msg;
	ctr_tlistitem* li;
	ctr_tlistitem* curlistitem;
	int lookAhead;
	int isBin;
	int first;
	ctr_size ulen;
	t = ctr_clex_tok();
	msgpartlen = ctr_clex_tok_value_length();
	if ((msgpartlen) > 255) {
		printf("Message too long\n");
		exit(1);
	}
	m = CTR_PARSER_CREATE_NODE();
	m->type = -1;
	s = ctr_clex_tok_value();
	msg = ctr_malloc(255*sizeof(char), 0);
	memcpy(msg, s, msgpartlen);
	ulen = ctr_getutf8len(msg, msgpartlen);
	isBin = (ulen == 1);
	if (mode == 2 && isBin) {
		ctr_clex_putback();
		return m;
	}
	if (isBin) {
		if (ctr_mode_debug) printf("Parsing binary message: '%s' (mode: %d)\n", msg, mode);
		m->type = CTR_AST_NODE_BINMESSAGE;
		m->value = msg;
		m->vlen = msgpartlen;
		li = CTR_PARSER_CREATE_LISTITEM();
		if (ctr_mode_debug) printf("Binary argument start..\n");
		li->node = ctr_cparse_expr(2);
		if (ctr_mode_debug) printf("Binary argument end..\n");
		m->nodes = li;
		return m;
	}
	lookAhead = ctr_clex_tok(); ctr_clex_putback();
	if (lookAhead == CTR_TOKEN_COLON) {
		if (mode > 0) {
			ctr_clex_putback();
			if (ctr_mode_debug) printf("> End of argument, next token: %s .\n", msg);
			return m;
		 }
		*(msg + msgpartlen) = ':';
		msgpartlen += 1;
		if ((msgpartlen) > 255) {
			printf("Message too long\n");
			exit(1);
		}
		if (ctr_mode_debug) printf("Message so far: %s\n", msg);
		m->type = CTR_AST_NODE_KWMESSAGE;
		t = ctr_clex_tok();
		first = 1;
		while(1) {
			li = CTR_PARSER_CREATE_LISTITEM();
			if (ctr_mode_debug) printf("Next arg, message so far: %s \n", msg);
			li->node = ctr_cparse_expr(1);
			if (ctr_mode_debug) printf("Argument of keyword message has been parsed.\n");
			if (first) {
				m->nodes = li;
				curlistitem = m->nodes;
				first = 0;
			} else {
				curlistitem->next = li;
				curlistitem = li;
			}
			t = ctr_clex_tok();
			if (ctr_mode_debug) printf("Next token after argument = %d \n", t);
			if (t == CTR_TOKEN_DOT) break;
			if (t == CTR_TOKEN_FIN) break;
			if (t == CTR_TOKEN_CHAIN) break;
			if (t == CTR_TOKEN_PARCLOSE) break;
			if (t == CTR_TOKEN_REF) {
				long l = ctr_clex_tok_value_length(); 
				if ((msgpartlen + l) > 255) {
					printf("Message too long\n");
					exit(1);
				}
				memcpy( (msg+msgpartlen), ctr_clex_tok_value(), l);
				msgpartlen = msgpartlen + l;
				*(msg + msgpartlen) = ':';
				msgpartlen ++;
				t = ctr_clex_tok();
				if (t != CTR_TOKEN_COLON) {
					printf("Expected colon. %s \n",msg);
					exit(1);
				}
			}
		}
		if (ctr_mode_debug) printf("Putting back.\n");
		ctr_clex_putback(); /* not a colon so put back */
		if (ctr_mode_debug) printf("Parsing keyword message: '%s' (mode: %d) \n", msg, mode);
		m->value = msg;
		m->vlen = msgpartlen;
	} else {
		m->type = CTR_AST_NODE_UNAMESSAGE;
		m->value = msg;
		m->vlen = msgpartlen;
		if (ctr_mode_debug) printf("Parsing unary message: '%s' (mode: %d) token = %d \n", msg, mode, lookAhead);
	}
	return m;
}