Branch: Tag:

2016-01-04

2016-01-04 14:57:56 by Per Hedbor <ph@opera.com>

First stage of the 'auto' type.

Works, but for now only for variable declarations, not return types
(entirely, most of the plumbing is done) or for variables declared in
foreach and sscanf.

Since the loop variables in foreach is really the most important
location, this is of somewhat limited use so far.

Commited for safekeeping.

Conflicts:
src/language.yacc
src/lexer.h
src/pike_types.c
src/svalue.h

98:   %token TOK_SAFE_INDEX   %token TOK_SAFE_START_INDEX   %token TOK_BITS + %token TOK_AUTO_ID         %right '='
245:   %type <number> TOK_SSCANF   %type <number> TOK_STATIC   %type <number> TOK_STRING_ID + %type <number> TOK_AUTO_ID   %type <number> TOK_SWITCH   %type <number> TOK_VOID_ID   %type <number> TOK_WHILE
908:    i = ID_FROM_INT(Pike_compiler->new_program, f);    i->opt_flags = Pike_compiler->compiler_frame->opt_flags;    +  if (Pike_compiler->compiler_pass == 2) +  { +  struct pike_type *t = Pike_compiler->compiler_frame->current_return_type; +  if( t->type == PIKE_T_AUTO ) +  { +  if( !t->car ) +  yyerror("'auto' without return statement is not allowed\n"); +  else +  { +  int e; +  struct pike_string *a = describe_type( t->car )->str; +  fprintf( stderr, "AUTO: -->%s\n", a); +  free_string( a ); +  /* push_finished_type( t->car );/\* return type.. *\/ */ +  +  /* for(; e>=0; e--) */ +  /* { */ +  /* push_finished_type(Pike_compiler->compiler_frame->variable[e].type); */ +  /* push_type(T_FUNCTION); */ +  /* } */ +  +  /* if ($2) { */ +  /* node *n = $2; */ +  /* while (n) { */ +  /* push_type_attribute(CDR(n)->u.sval.u.string); */ +  /* n = CAR(n); */ +  /* } */ +  /* } */ +  /* free_type( i->type ); */ +  /* i->type = compiler_pop_type(); */ +  } +  } +  } +    #ifdef PIKE_DEBUG    if(Pike_interpreter.recoveries &&    ((Pike_sp - Pike_interpreter.evaluator_stack) <
931:    for (e = Pike_compiler->compiler_frame->current_number_of_locals; e--;) {    Pike_compiler->compiler_frame->variable[e].flags |= LOCAL_VAR_IS_USED;    } +  if( Pike_compiler->compiler_frame->current_return_type->type == PIKE_T_AUTO ) +  yyerror("'auto' return type not allowed for prototypes\n");    }   #ifdef PIKE_DEBUG    if (Pike_compiler->compiler_frame != $7) {
1118:    | TOK_INT_ID { $$ = "int"; }    | TOK_ENUM { $$ = "enum"; }    | TOK_TYPEDEF { $$ = "typedef"; } +  /* | TOK_AUTO_ID { $$ = "auto"; } */    ;      magic_identifiers3:
1283:    TOK_FLOAT_ID { push_type(T_FLOAT); }    | TOK_VOID_ID { push_type(T_VOID); }    | TOK_MIXED_ID { push_type(T_MIXED); } +  | TOK_AUTO_ID { push_type(PIKE_T_AUTO); }    | TOK_STRING_ID opt_string_width {}    | TOK_INT_ID opt_int_range {}    | TOK_MAPPING_ID opt_mapping_type {}
1706:    $2->u.sval.u.string->str);    }   #endif /* PIKE_DEBUG */ +  if(is_auto_variable_type( $<number>4 )) +  { +  // auto variable type needs to be updated. +  fix_auto_variable_type( $<number>4, $5->type ); +  }    free_node($5);    $5 = NULL;    }    }    if ($5) { -  +  if( Pike_compiler->compiler_pass == 2 && is_auto_variable_type( $<number>4 ) ) +  { +  fix_type_field( $5 ); +  fix_auto_variable_type( $<number>4, $5->type ); +  }    Pike_compiler->init_node=mknode(F_COMMA_EXPR,Pike_compiler->init_node,    mkcastnode(void_type_string,    mknode(F_ASSIGN,$5,
1750:    | optional_stars TOK_IDENTIFIER '=' expr0    {    int id; +  struct pike_type *type;    push_finished_type($<n>0->u.sval.u.type); -  id = add_local_name($2->u.sval.u.string, compiler_pop_type(),0); +  id = add_local_name($2->u.sval.u.string, (type=compiler_pop_type()),0); +  if( type->type == PIKE_T_AUTO && Pike_compiler->compiler_pass == 2) +  { +  free_type( type ); +  fix_type_field( $4 ); +  copy_pike_type( type, $4->type ); +  }    if (id >= 0) {    if (!(THIS_COMPILATION->lex.pragmas & ID_STRICT_TYPES)) {    /* Only warn about unused initialized variables in strict types mode. */