]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Merge branch 'correct'
authorDale Weiler <killfieldengine@gmail.com>
Fri, 4 Jan 2013 11:56:07 +0000 (11:56 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Fri, 4 Jan 2013 11:56:07 +0000 (11:56 +0000)
1  2 
parser.c

diff --combined parser.c
index 229d2ec0da2c6495cad77c3b4d4f3eb1fb67db85,b7831d4e1d9f65dfc05147f9107bdf38defa9d2b..2d7ebe3941b6010999cd99ec82690ef11c16280b
+++ b/parser.c
@@@ -74,6 -74,10 +74,10 @@@ typedef struct 
      ht htglobals;
      ht *typedefs;
  
+     /* same as above but for the spelling corrector */
+     ht       *correct_variables;
+     size_t ***correct_variables_score;  /* vector of vector of size_t* */
      /* not to be used directly, we use the hash table */
      ast_expression **_locals;
      size_t          *_blocklocals;
@@@ -1614,13 -1618,15 +1618,15 @@@ static ast_expression* parse_expression
                  }
                  else
                  {
+                     size_t i;
+                     char  *correct = NULL;
                      /*
                       * sometimes people use preprocessing predefs without enabling them
                       * i've done this thousands of times already myself.  Lets check for
                       * it in the predef table.  And diagnose it better :)
                       */
                      if (!OPTS_FLAG(FTEPP_PREDEFS)) {
-                         size_t i;
                          for (i = 0; i < sizeof(ftepp_predefs)/sizeof(*ftepp_predefs); i++) {
                              if (!strcmp(ftepp_predefs[i].name, parser_tokval(parser))) {
                                  parseerror(parser, "unexpected ident: %s (use -fftepp-predef to enable pre-defined macros)", parser_tokval(parser));
                          }
                      }
  
-                     parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
+                     /*
+                      * TODO: determine the best score for the identifier: be it
+                      * a variable, a field.
+                      *
+                      * We should also consider adding correction tables for
+                      * other things as well.
+                      */
+                     for (i = 0; i < vec_size(parser->correct_variables); i++) {
+                         correct = correct_str(parser->correct_variables[i], "ello");
+                         if (strcmp(correct, parser_tokval(parser))) {
+                             break;
+                         } else if (correct) {
+                             mem_d(correct);
+                         }
+                     }
+                     if (correct) {
+                         parseerror(parser, "unexpected ident: %s (did you mean %s?)", parser_tokval(parser), correct);
+                         mem_d(correct);
+                     } else {
+                         parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
+                     }
                      goto onerr;
                  }
              }
@@@ -1968,6 -1996,10 +1996,10 @@@ static void parser_enterblock(parser_t 
      vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE));
      vec_push(parser->_blocktypedefs, vec_size(parser->_typedefs));
      vec_push(parser->_block_ctx, parser_ctx(parser));
+     /* corrector */
+     vec_push(parser->correct_variables, util_htnew(PARSER_HT_SIZE));
+     vec_push(parser->correct_variables_score, NULL);
  }
  
  static bool parser_leaveblock(parser_t *parser)
      }
  
      util_htdel(vec_last(parser->variables));
+     correct_del(vec_last(parser->correct_variables), vec_last(parser->correct_variables_score));
      vec_pop(parser->variables);
+     vec_pop(parser->correct_variables);
+     vec_pop(parser->correct_variables_score);
      if (!vec_size(parser->_blocklocals)) {
          parseerror(parser, "internal error: parser_leaveblock with no block (2)");
          return false;
      vec_pop(parser->typedefs);
  
      vec_pop(parser->_block_ctx);
      return rv;
  }
  
@@@ -2015,6 -2052,13 +2052,13 @@@ static void parser_addlocal(parser_t *p
  {
      vec_push(parser->_locals, e);
      util_htset(vec_last(parser->variables), name, (void*)e);
+     /* corrector */
+     correct_add (
+          vec_last(parser->correct_variables),
+         &vec_last(parser->correct_variables_score),
+         name
+     );
  }
  
  static ast_expression* process_condition(parser_t *parser, ast_expression *cond, bool *_ifnot)
@@@ -2999,35 -3043,28 +3043,35 @@@ static bool parse_switch_go(parser_t *p
  }
  
  /* parse computed goto sides */
 -static ast_expression *parse_goto_computed(parser_t *parser, ast_expression *side) {
 +static ast_expression *parse_goto_computed(parser_t *parser, ast_expression **side) {
      ast_expression *on_true;
      ast_expression *on_false;
 +    ast_expression *cond;
  
 -    if (!side)
 +    if (!*side)
          return NULL;
  
 -    if (ast_istype(side, ast_ternary)) {
 -        on_true  = parse_goto_computed(parser, ((ast_ternary*)side)->on_true);
 -        on_false = parse_goto_computed(parser, ((ast_ternary*)side)->on_false);
 +    if (ast_istype(*side, ast_ternary)) {
 +        ast_ternary *tern = (ast_ternary*)*side;
 +        on_true  = parse_goto_computed(parser, &tern->on_true);
 +        on_false = parse_goto_computed(parser, &tern->on_false);
  
          if (!on_true || !on_false) {
              parseerror(parser, "expected label or expression in ternary");
 -            if (((ast_ternary*)side)->on_false) ast_unref(((ast_ternary*)side)->on_false);
 -            if (((ast_ternary*)side)->on_true)  ast_unref(((ast_ternary*)side)->on_true);
 +            if (on_true) ast_unref(on_true);
 +            if (on_false) ast_unref(on_false);
              return NULL;
          }
  
 -        return (ast_expression*)ast_ifthen_new(parser_ctx(parser), ((ast_ternary*)side)->cond, on_true, on_false);
 -    } else if (ast_istype(side, ast_label)) {
 -        ast_goto *gt = ast_goto_new(parser_ctx(parser), ((ast_label*)side)->name);
 -        ast_goto_set_label(gt, ((ast_label*)side));
 +        cond = tern->cond;
 +        tern->cond = NULL;
 +        ast_delete(tern);
 +        *side = NULL;
 +        return (ast_expression*)ast_ifthen_new(parser_ctx(parser), cond, on_true, on_false);
 +    } else if (ast_istype(*side, ast_label)) {
 +        ast_goto *gt = ast_goto_new(parser_ctx(parser), ((ast_label*)*side)->name);
 +        ast_goto_set_label(gt, ((ast_label*)*side));
 +        *side = NULL;
          return (ast_expression*)gt;
      }
      return NULL;
@@@ -3052,7 -3089,7 +3096,7 @@@ static bool parse_goto(parser_t *parser
  
          /* failed to parse expression for goto */
          if (!(expression = parse_expression(parser, false, true)) ||
 -            !(*out = parse_goto_computed(parser, expression))) {
 +            !(*out = parse_goto_computed(parser, &expression))) {
              parseerror(parser, "invalid goto expression");
              ast_unref(expression);
              return false;
@@@ -3549,6 -3586,7 +3593,7 @@@ static bool parse_function_body(parser_
  
              vec_push(parser->globals, (ast_expression*)thinkfunc);
              util_htset(parser->htglobals, thinkfunc->name, thinkfunc);
              nextthink = (ast_expression*)thinkfunc;
  
          } else {
@@@ -4790,6 -4828,14 +4835,14 @@@ static bool parse_variable(parser_t *pa
  
                      /* Add it to the local scope */
                      util_htset(vec_last(parser->variables), var->name, (void*)var);
+                     /* corrector */
+                     correct_add (
+                          vec_last(parser->correct_variables),
+                         &vec_last(parser->correct_variables_score),
+                         var->name
+                     );
                      /* now rename the global */
                      ln = strlen(var->name);
                      vec_append(defname, ln, var->name);
                          for (i = 0; i < 3; ++i) {
                              util_htset(vec_last(parser->variables), me[i]->name, (void*)(me[i]));
  
+                             /* corrector */
+                             correct_add(
+                                  vec_last(parser->correct_variables),
+                                 &vec_last(parser->correct_variables_score),
+                                 me[i]->name
+                             );
                              vec_shrinkto(defname, prefix_len);
                              ln = strlen(me[i]->name);
                              vec_append(defname, ln, me[i]->name);
@@@ -5349,6 -5402,17 +5409,17 @@@ void parser_cleanup(
      vec_free(parser->_blocklocals);
      vec_free(parser->_locals);
  
+     /* corrector */
+     for (i = 0; i < vec_size(parser->correct_variables); ++i) {
+         correct_del(parser->correct_variables[i], parser->correct_variables_score[i]);
+     }
+     for (i = 0; i < vec_size(parser->correct_variables_score); ++i) {
+         vec_free(parser->correct_variables_score[i]);
+     }
+     vec_free(parser->correct_variables);
+     vec_free(parser->correct_variables_score);
      for (i = 0; i < vec_size(parser->_typedefs); ++i)
          ast_delete(parser->_typedefs[i]);
      vec_free(parser->_typedefs);