Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #4
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;
}
Beispiel #5
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;
}
Beispiel #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;
}
Beispiel #7
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;
}
Beispiel #8
0
/**
 * CTRParserCreateNode
 *
 * Creates a parser node and adds it to the source map.
 */
ctr_tnode *
ctr_cparse_create_node (int type)
{
  ctr_tnode *node = (ctr_tnode *) ctr_heap_allocate_tracked (sizeof (ctr_tnode));
  if (ctr_source_mapping)
    {
      ctr_source_map *m = (ctr_source_map *) ctr_heap_allocate_tracked (sizeof (ctr_source_map));
      m->line = ctr_clex_line_number;
      m->node = node;
      m->p_ptr = ctr_code;
      m->e_ptr = ctr_clex_code_end;
      m->s_ptr = ctr_clex_code_init;
      if (ctr_source_map_head)
	{
	  m->next = ctr_source_map_head;
	  ctr_source_map_head = m;
	}
      else
	{
	  ctr_source_map_head = m;
	}
    }
  return node;
}
Beispiel #9
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;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
0
/**
 * [File] include
 *
 * Includes the file as a piece of executable code.
 */
ctr_object* ctr_file_include(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* path = ctr_internal_object_find_property(myself, ctr_build_string_from_cstring( "path" ), 0);
	ctr_tnode* parsedCode;
	ctr_size vlen;
	char* pathString;
	char* prg;
	uint64_t program_size = 0;
	if (path == NULL) return myself;
	vlen = path->value.svalue->vlen;
	pathString = ctr_heap_allocate_tracked(sizeof(char)*(vlen+1)); //needed until end, pathString appears in stracktrace
	memcpy(pathString, path->value.svalue->value, vlen);
	memcpy(pathString+vlen,"\0",1);
	prg = ctr_internal_readf(pathString, &program_size);
	parsedCode = ctr_cparse_parse(prg, pathString);
	ctr_heap_free( prg );
	ctr_cwlk_subprogram++;
	ctr_cwlk_run(parsedCode);
	ctr_cwlk_subprogram--;
	return myself;
}
Beispiel #14
0
/**
 * CommandLine Read Arguments
 * Parses command line arguments and sets global settings accordingly.
 */
void
ctr_cli_read_args (int argc, char *argv[])
{
  if (argc == 1 || argv == NULL)
    {
      ctr_cli_welcome (argv[0]);
      exit (0);
    }
  argc--;
  argv++;
  while (argc > 0 && argv && argv[0][0] == '-')
    {
      if (strcmp (argv[0], "-c") == 0 || strcmp (argv[0], "--compile") == 0)
	compile_and_quit = 1;
      else if (strcmp (argv[0], "-fc") == 0 || strcmp (argv[0], "--from-compiled") == 0)
	compile_and_quit = 2;
      else if (strcmp (argv[0], "-d") == 0)
	debug = 1;
      else if (strcmp (argv[0], "-e") == 0)
	from_stdin = 1;
      else if (strcmp (argv[0], "--ext") == 0)
	{
	  puts (ctr_file_stdext_path_raw ());
	  exit (0);
	}
      else
	break;
      argv++;
      argc--;
    }
  if (!from_stdin && argv == NULL)
    {
      ctr_question_intent ();
      exit (0);
    }
  ctr_mode_input_file = (char *) ctr_heap_allocate_tracked (sizeof (char) * 255);
  strncpy (ctr_mode_input_file, from_stdin ? "<stdin>" : argv[0], 254);
}
Beispiel #15
0
/**
 * 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;
}
Beispiel #16
0
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;
}
Beispiel #17
0
/**
 * 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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
/**
 * 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;
}