mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-07-29 02:20:04 +02:00
fixes #428 :: apply DMDFE 1.061; thanks SiegeLord
This commit is contained in:
@@ -338,7 +338,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
if (!tc->sym->symtab || tc->sym->sizeok == 0)
|
if (!tc->sym->symtab || tc->sym->sizeok == 0)
|
||||||
{ // Try to resolve forward reference
|
{ // Try to resolve forward reference
|
||||||
if (sc->mustsemantic && tc->sym->scope)
|
if (/*sc->mustsemantic &&*/ tc->sym->scope)
|
||||||
tc->sym->semantic(NULL);
|
tc->sym->semantic(NULL);
|
||||||
}
|
}
|
||||||
if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0)
|
if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0)
|
||||||
@@ -406,7 +406,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
|
|
||||||
if (!tc->sym->symtab)
|
if (!tc->sym->symtab)
|
||||||
{ // Try to resolve forward reference
|
{ // Try to resolve forward reference
|
||||||
if (sc->mustsemantic && tc->sym->scope)
|
if (/*sc->mustsemantic &&*/ tc->sym->scope)
|
||||||
tc->sym->semantic(NULL);
|
tc->sym->semantic(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ void AliasDeclaration::semantic(Scope *sc)
|
|||||||
//printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
|
//printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
|
||||||
type = NULL;
|
type = NULL;
|
||||||
VarDeclaration *v = s->isVarDeclaration();
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
if (v && v->linkage == LINKdefault)
|
if (0 && v && v->linkage == LINKdefault)
|
||||||
{
|
{
|
||||||
error("forward reference of %s", v->toChars());
|
error("forward reference of %s", v->toChars());
|
||||||
s = NULL;
|
s = NULL;
|
||||||
@@ -831,8 +831,8 @@ void VarDeclaration::semantic(Scope *sc)
|
|||||||
OutBuffer buf;
|
OutBuffer buf;
|
||||||
buf.printf("_%s_field_%zu", ident->toChars(), i);
|
buf.printf("_%s_field_%zu", ident->toChars(), i);
|
||||||
buf.writeByte(0);
|
buf.writeByte(0);
|
||||||
char *name = (char *)buf.extractData();
|
const char *name = (const char *)buf.extractData();
|
||||||
Identifier *id = new Identifier(name, TOKidentifier);
|
Identifier *id = Lexer::idPool(name);
|
||||||
|
|
||||||
Expression *einit = ie;
|
Expression *einit = ie;
|
||||||
if (ie && ie->op == TOKtuple)
|
if (ie && ie->op == TOKtuple)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
#include "speller.h"
|
#include "speller.h"
|
||||||
|
#include "aav.h"
|
||||||
|
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
#include "dsymbol.h"
|
#include "dsymbol.h"
|
||||||
@@ -1197,60 +1198,89 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
|
|||||||
|
|
||||||
DsymbolTable::DsymbolTable()
|
DsymbolTable::DsymbolTable()
|
||||||
{
|
{
|
||||||
|
#if STRINGTABLE
|
||||||
tab = new StringTable;
|
tab = new StringTable;
|
||||||
|
#else
|
||||||
|
tab = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
DsymbolTable::~DsymbolTable()
|
DsymbolTable::~DsymbolTable()
|
||||||
{
|
{
|
||||||
|
#if STRINGTABLE
|
||||||
delete tab;
|
delete tab;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Dsymbol *DsymbolTable::lookup(Identifier *ident)
|
Dsymbol *DsymbolTable::lookup(Identifier *ident)
|
||||||
{
|
{
|
||||||
|
#if STRINGTABLE
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
assert(ident);
|
assert(ident);
|
||||||
assert(tab);
|
assert(tab);
|
||||||
#endif
|
#endif
|
||||||
|
//printf("DsymbolTable::lookup(%s)\n", (char*)ident->string);
|
||||||
StringValue *sv = tab->lookup((char*)ident->string, ident->len);
|
StringValue *sv = tab->lookup((char*)ident->string, ident->len);
|
||||||
return (Dsymbol *)(sv ? sv->ptrvalue : NULL);
|
return (Dsymbol *)(sv ? sv->ptrvalue : NULL);
|
||||||
|
#else
|
||||||
|
//printf("DsymbolTable::lookup(%s)\n", (char*)ident->string);
|
||||||
|
return (Dsymbol *)_aaGetRvalue(tab, ident);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Dsymbol *DsymbolTable::insert(Dsymbol *s)
|
Dsymbol *DsymbolTable::insert(Dsymbol *s)
|
||||||
{ StringValue *sv;
|
{
|
||||||
Identifier *ident;
|
|
||||||
|
|
||||||
//printf("DsymbolTable::insert(this = %p, '%s')\n", this, s->ident->toChars());
|
//printf("DsymbolTable::insert(this = %p, '%s')\n", this, s->ident->toChars());
|
||||||
ident = s->ident;
|
Identifier *ident = s->ident;
|
||||||
|
#if STRINGTABLE
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
assert(ident);
|
assert(ident);
|
||||||
assert(tab);
|
assert(tab);
|
||||||
#endif
|
#endif
|
||||||
sv = tab->insert(ident->toChars(), ident->len);
|
StringValue *sv = tab->insert(ident->toChars(), ident->len);
|
||||||
if (!sv)
|
if (!sv)
|
||||||
return NULL; // already in table
|
return NULL; // already in table
|
||||||
sv->ptrvalue = s;
|
sv->ptrvalue = s;
|
||||||
return s;
|
return s;
|
||||||
|
#else
|
||||||
|
Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident);
|
||||||
|
if (*ps)
|
||||||
|
return NULL; // already in table
|
||||||
|
*ps = s;
|
||||||
|
return s;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Dsymbol *DsymbolTable::insert(Identifier *ident, Dsymbol *s)
|
Dsymbol *DsymbolTable::insert(Identifier *ident, Dsymbol *s)
|
||||||
{ StringValue *sv;
|
{
|
||||||
|
|
||||||
//printf("DsymbolTable::insert()\n");
|
//printf("DsymbolTable::insert()\n");
|
||||||
sv = tab->insert(ident->toChars(), ident->len);
|
#if STRINGTABLE
|
||||||
|
StringValue *sv = tab->insert(ident->toChars(), ident->len);
|
||||||
if (!sv)
|
if (!sv)
|
||||||
return NULL; // already in table
|
return NULL; // already in table
|
||||||
sv->ptrvalue = s;
|
sv->ptrvalue = s;
|
||||||
return s;
|
return s;
|
||||||
|
#else
|
||||||
|
Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident);
|
||||||
|
if (*ps)
|
||||||
|
return NULL; // already in table
|
||||||
|
*ps = s;
|
||||||
|
return s;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Dsymbol *DsymbolTable::update(Dsymbol *s)
|
Dsymbol *DsymbolTable::update(Dsymbol *s)
|
||||||
{ StringValue *sv;
|
{
|
||||||
Identifier *ident;
|
Identifier *ident = s->ident;
|
||||||
|
#if STRINGTABLE
|
||||||
ident = s->ident;
|
StringValue *sv = tab->update(ident->toChars(), ident->len);
|
||||||
sv = tab->update(ident->toChars(), ident->len);
|
|
||||||
sv->ptrvalue = s;
|
sv->ptrvalue = s;
|
||||||
return s;
|
return s;
|
||||||
|
#else
|
||||||
|
Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident);
|
||||||
|
*ps = s;
|
||||||
|
return s;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ struct HdrGenState;
|
|||||||
struct TypeInfoDeclaration;
|
struct TypeInfoDeclaration;
|
||||||
struct ClassInfoDeclaration;
|
struct ClassInfoDeclaration;
|
||||||
struct OverloadSet;
|
struct OverloadSet;
|
||||||
|
struct AA;
|
||||||
#if TARGET_NET
|
#if TARGET_NET
|
||||||
struct PragmaScope;
|
struct PragmaScope;
|
||||||
#endif
|
#endif
|
||||||
@@ -355,7 +356,11 @@ struct OverloadSet : Dsymbol
|
|||||||
|
|
||||||
struct DsymbolTable : Object
|
struct DsymbolTable : Object
|
||||||
{
|
{
|
||||||
|
#if STRINGTABLE
|
||||||
StringTable *tab;
|
StringTable *tab;
|
||||||
|
#else
|
||||||
|
AA *tab;
|
||||||
|
#endif
|
||||||
|
|
||||||
DsymbolTable();
|
DsymbolTable();
|
||||||
~DsymbolTable();
|
~DsymbolTable();
|
||||||
|
|||||||
@@ -2131,12 +2131,17 @@ Expression *IdentifierExp::semantic(Scope *sc)
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
const char *n = importHint(ident->toChars());
|
||||||
s = sc->search_correct(ident);
|
if (n)
|
||||||
if (s)
|
error("'%s' is not defined, perhaps you need to import %s; ?", ident->toChars(), n);
|
||||||
error("undefined identifier %s, did you mean %s %s?", ident->toChars(), s->kind(), s->toChars());
|
|
||||||
else
|
else
|
||||||
error("undefined identifier %s", ident->toChars());
|
{
|
||||||
|
s = sc->search_correct(ident);
|
||||||
|
if (s)
|
||||||
|
error("undefined identifier %s, did you mean %s %s?", ident->toChars(), s->kind(), s->toChars());
|
||||||
|
else
|
||||||
|
error("undefined identifier %s", ident->toChars());
|
||||||
|
}
|
||||||
return new ErrorExp();
|
return new ErrorExp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2251,7 +2256,9 @@ Lagain:
|
|||||||
{
|
{
|
||||||
//printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
|
//printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
|
||||||
if (!type)
|
if (!type)
|
||||||
{ type = v->type;
|
{ if (!v->type && v->scope)
|
||||||
|
v->semantic(v->scope);
|
||||||
|
type = v->type;
|
||||||
if (!v->type)
|
if (!v->type)
|
||||||
{ error("forward reference of %s", v->toChars());
|
{ error("forward reference of %s", v->toChars());
|
||||||
type = Type::terror;
|
type = Type::terror;
|
||||||
@@ -2299,6 +2306,9 @@ Lagain:
|
|||||||
f = s->isFuncDeclaration();
|
f = s->isFuncDeclaration();
|
||||||
if (f)
|
if (f)
|
||||||
{ //printf("'%s' is a function\n", f->toChars());
|
{ //printf("'%s' is a function\n", f->toChars());
|
||||||
|
|
||||||
|
if (!f->originalType && f->scope) // semantic not yet run
|
||||||
|
f->semantic(f->scope);
|
||||||
if (!f->type->deco)
|
if (!f->type->deco)
|
||||||
{
|
{
|
||||||
error("forward reference to %s", toChars());
|
error("forward reference to %s", toChars());
|
||||||
@@ -3510,33 +3520,36 @@ Expression *ScopeExp::semantic(Scope *sc)
|
|||||||
Lagain:
|
Lagain:
|
||||||
ti = sds->isTemplateInstance();
|
ti = sds->isTemplateInstance();
|
||||||
if (ti && !global.errors)
|
if (ti && !global.errors)
|
||||||
{ Dsymbol *s;
|
{
|
||||||
if (!ti->semanticRun)
|
if (!ti->semanticRun)
|
||||||
ti->semantic(sc);
|
ti->semantic(sc);
|
||||||
s = ti->inst->toAlias();
|
if (ti->inst)
|
||||||
sds2 = s->isScopeDsymbol();
|
|
||||||
if (!sds2)
|
|
||||||
{ Expression *e;
|
|
||||||
|
|
||||||
//printf("s = %s, '%s'\n", s->kind(), s->toChars());
|
|
||||||
if (ti->withsym)
|
|
||||||
{
|
|
||||||
// Same as wthis.s
|
|
||||||
e = new VarExp(loc, ti->withsym->withstate->wthis);
|
|
||||||
e = new DotVarExp(loc, e, s->isDeclaration());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
e = new DsymbolExp(loc, s);
|
|
||||||
e = e->semantic(sc);
|
|
||||||
//printf("-1ScopeExp::semantic()\n");
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
if (sds2 != sds)
|
|
||||||
{
|
{
|
||||||
sds = sds2;
|
Dsymbol *s = ti->inst->toAlias();
|
||||||
goto Lagain;
|
sds2 = s->isScopeDsymbol();
|
||||||
|
if (!sds2)
|
||||||
|
{ Expression *e;
|
||||||
|
|
||||||
|
//printf("s = %s, '%s'\n", s->kind(), s->toChars());
|
||||||
|
if (ti->withsym)
|
||||||
|
{
|
||||||
|
// Same as wthis.s
|
||||||
|
e = new VarExp(loc, ti->withsym->withstate->wthis);
|
||||||
|
e = new DotVarExp(loc, e, s->isDeclaration());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
e = new DsymbolExp(loc, s);
|
||||||
|
e = e->semantic(sc);
|
||||||
|
//printf("-1ScopeExp::semantic()\n");
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if (sds2 != sds)
|
||||||
|
{
|
||||||
|
sds = sds2;
|
||||||
|
goto Lagain;
|
||||||
|
}
|
||||||
|
//printf("sds = %s, '%s'\n", sds->kind(), sds->toChars());
|
||||||
}
|
}
|
||||||
//printf("sds = %s, '%s'\n", sds->kind(), sds->toChars());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
parent = sc->parent;
|
parent = sc->parent;
|
||||||
Dsymbol *parent = toParent();
|
Dsymbol *parent = toParent();
|
||||||
|
|
||||||
if (semanticRun == PASSsemanticdone)
|
if (semanticRun >= PASSsemanticdone)
|
||||||
{
|
{
|
||||||
if (!parent->isClassDeclaration())
|
if (!parent->isClassDeclaration())
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ Global::Global()
|
|||||||
|
|
||||||
copyright = "Copyright (c) 1999-2010 by Digital Mars and Tomas Lindquist Olsen";
|
copyright = "Copyright (c) 1999-2010 by Digital Mars and Tomas Lindquist Olsen";
|
||||||
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
||||||
version = "v1.060";
|
version = "v1.061";
|
||||||
ldc_version = LDC_REV;
|
ldc_version = LDC_REV;
|
||||||
llvm_version = LLVM_REV_STR;
|
llvm_version = LLVM_REV_STR;
|
||||||
global.structalign = 8;
|
global.structalign = 8;
|
||||||
|
|||||||
@@ -442,6 +442,8 @@ void err_nomem();
|
|||||||
void inifile(char *argv0, const char *inifile);
|
void inifile(char *argv0, const char *inifile);
|
||||||
void halt();
|
void halt();
|
||||||
|
|
||||||
|
const char *importHint(const char *s);
|
||||||
|
|
||||||
/*** Where to send error messages ***/
|
/*** Where to send error messages ***/
|
||||||
#if IN_GCC || IN_LLVM
|
#if IN_GCC || IN_LLVM
|
||||||
#define stdmsg stderr
|
#define stdmsg stderr
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ Expression *fromConstInitializer(Expression *e1)
|
|||||||
if (e1->op == TOKvar)
|
if (e1->op == TOKvar)
|
||||||
{ VarExp *ve = (VarExp *)e1;
|
{ VarExp *ve = (VarExp *)e1;
|
||||||
VarDeclaration *v = ve->var->isVarDeclaration();
|
VarDeclaration *v = ve->var->isVarDeclaration();
|
||||||
|
if (v && !v->originalType && v->scope) // semantic() not yet run
|
||||||
|
v->semantic (v->scope);
|
||||||
if (v && v->isConst() && v->init)
|
if (v && v->isConst() && v->init)
|
||||||
{ Expression *ei = v->init->toExpression();
|
{ Expression *ei = v->init->toExpression();
|
||||||
if (ei && ei->type)
|
if (ei && ei->type)
|
||||||
|
|||||||
14
dmd/scope.c
14
dmd/scope.c
@@ -23,6 +23,7 @@
|
|||||||
#include "aggregate.h"
|
#include "aggregate.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
|
#include "lexer.h"
|
||||||
|
|
||||||
Scope *Scope::freelist = NULL;
|
Scope *Scope::freelist = NULL;
|
||||||
|
|
||||||
@@ -372,10 +373,19 @@ void Scope::setNoFree()
|
|||||||
void *scope_search_fp(void *arg, const char *seed)
|
void *scope_search_fp(void *arg, const char *seed)
|
||||||
{
|
{
|
||||||
//printf("scope_search_fp('%s')\n", seed);
|
//printf("scope_search_fp('%s')\n", seed);
|
||||||
|
|
||||||
|
/* If not in the lexer's string table, it certainly isn't in the symbol table.
|
||||||
|
* Doing this first is a lot faster.
|
||||||
|
*/
|
||||||
|
StringValue *sv = Lexer::stringtable.lookup(seed, strlen(seed));
|
||||||
|
if (!sv)
|
||||||
|
return NULL;
|
||||||
|
Identifier *id = (Identifier *)sv->ptrvalue;
|
||||||
|
assert(id);
|
||||||
|
|
||||||
Scope *sc = (Scope *)arg;
|
Scope *sc = (Scope *)arg;
|
||||||
Identifier id(seed, 0);
|
|
||||||
Module::clearCache();
|
Module::clearCache();
|
||||||
Dsymbol *s = sc->search(0, &id, NULL);
|
Dsymbol *s = sc->search(0, id, NULL);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
216
dmd/speller.c
216
dmd/speller.c
@@ -2,6 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "speller.h"
|
#include "speller.h"
|
||||||
|
|
||||||
@@ -12,112 +13,188 @@ const char idchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123
|
|||||||
* Currently only looks a 'distance' of one from the seed[].
|
* Currently only looks a 'distance' of one from the seed[].
|
||||||
* This does an exhaustive search, so can potentially be very slow.
|
* This does an exhaustive search, so can potentially be very slow.
|
||||||
* Input:
|
* Input:
|
||||||
*seedwrongly spelled word
|
* seed wrongly spelled word
|
||||||
*fpsearch function
|
* fp search function
|
||||||
*fpargargument to search function
|
* fparg argument to search function
|
||||||
*charsetcharacter set
|
* charset character set
|
||||||
* Returns:
|
* Returns:
|
||||||
*NULLno correct spellings found
|
* NULL no correct spellings found
|
||||||
*void*value returned by fp() for first possible correct spelling
|
* void* value returned by fp() for first possible correct spelling
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *spellerX(const char *seed, fp_speller_t fp, void *fparg, const char *charset, int flag)
|
void *spellerY(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
|
||||||
|
const char *charset, size_t index)
|
||||||
|
{
|
||||||
|
if (!seedlen)
|
||||||
|
return NULL;
|
||||||
|
assert(seed[seedlen] == 0);
|
||||||
|
|
||||||
|
char tmp[30];
|
||||||
|
char *buf;
|
||||||
|
if (seedlen <= sizeof(tmp) - 2)
|
||||||
|
buf = tmp;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = (char *)alloca(seedlen + 2); // leave space for extra char
|
||||||
|
if (!buf)
|
||||||
|
return NULL; // no matches
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf, seed, index);
|
||||||
|
|
||||||
|
/* Delete at seed[index] */
|
||||||
|
if (index < seedlen)
|
||||||
|
{
|
||||||
|
memcpy(buf + index, seed + index + 1, seedlen - index);
|
||||||
|
assert(buf[seedlen - 1] == 0);
|
||||||
|
void *p = (*fp)(fparg, buf);
|
||||||
|
if (p)
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (charset && *charset)
|
||||||
|
{
|
||||||
|
/* Substitutions */
|
||||||
|
if (index < seedlen)
|
||||||
|
{
|
||||||
|
memcpy(buf, seed, seedlen + 1);
|
||||||
|
for (const char *s = charset; *s; s++)
|
||||||
|
{
|
||||||
|
buf[index] = *s;
|
||||||
|
|
||||||
|
//printf("sub buf = '%s'\n", buf);
|
||||||
|
void *p = (*fp)(fparg, buf);
|
||||||
|
if (p)
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
assert(buf[seedlen] == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insertions */
|
||||||
|
memcpy (buf + index + 1, seed + index, seedlen + 1 - index);
|
||||||
|
|
||||||
|
for (const char *s = charset; *s; s++)
|
||||||
|
{
|
||||||
|
buf[index] = *s;
|
||||||
|
|
||||||
|
//printf("ins buf = '%s'\n", buf);
|
||||||
|
void *p = (*fp)(fparg, buf);
|
||||||
|
if (p)
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
assert(buf[seedlen + 1] == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL; // didn't find any corrections
|
||||||
|
}
|
||||||
|
|
||||||
|
void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
|
||||||
|
const char *charset, int flag)
|
||||||
{
|
{
|
||||||
size_t seedlen = strlen(seed);
|
|
||||||
if (!seedlen)
|
if (!seedlen)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
char *buf = (char *)alloca(seedlen + 2);// leave space for extra char
|
char tmp[30];
|
||||||
if (!buf)
|
char *buf;
|
||||||
return NULL;// no matches
|
if (seedlen <= sizeof(tmp) - 2)
|
||||||
|
buf = tmp;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = (char *)alloca(seedlen + 2); // leave space for extra char
|
||||||
|
if (!buf)
|
||||||
|
return NULL; // no matches
|
||||||
|
}
|
||||||
|
|
||||||
/* Deletions */
|
/* Deletions */
|
||||||
memcpy(buf, seed + 1, seedlen);
|
memcpy(buf, seed + 1, seedlen);
|
||||||
for (int i = 0; i < seedlen; i++)
|
for (int i = 0; i < seedlen; i++)
|
||||||
{
|
{
|
||||||
//printf("del buf = '%s'\n", buf);
|
//printf("del buf = '%s'\n", buf);
|
||||||
void *p;
|
void *p;
|
||||||
if (flag)
|
if (flag)
|
||||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
p = spellerY(buf, seedlen - 1, fp, fparg, charset, i);
|
||||||
else
|
else
|
||||||
p = (*fp)(fparg, buf);
|
p = (*fp)(fparg, buf);
|
||||||
if (p)
|
if (p)
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
buf[i] = seed[i];
|
buf[i] = seed[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transpositions */
|
/* Transpositions */
|
||||||
memcpy(buf, seed, seedlen + 1);
|
if (!flag)
|
||||||
for (int i = 0; i + 1 < seedlen; i++)
|
{
|
||||||
|
memcpy(buf, seed, seedlen + 1);
|
||||||
|
for (int i = 0; i + 1 < seedlen; i++)
|
||||||
{
|
{
|
||||||
// swap [i] and [i + 1]
|
// swap [i] and [i + 1]
|
||||||
buf[i] = seed[i + 1];
|
buf[i] = seed[i + 1];
|
||||||
buf[i + 1] = seed[i];
|
buf[i + 1] = seed[i];
|
||||||
|
|
||||||
//printf("tra buf = '%s'\n", buf);
|
//printf("tra buf = '%s'\n", buf);
|
||||||
void *p;
|
void *p = (*fp)(fparg, buf);
|
||||||
if (flag)
|
|
||||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
|
||||||
else
|
|
||||||
p = (*fp)(fparg, buf);
|
|
||||||
if (p)
|
if (p)
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
buf[i] = seed[i];
|
buf[i] = seed[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (charset && *charset)
|
if (charset && *charset)
|
||||||
|
{
|
||||||
|
/* Substitutions */
|
||||||
|
memcpy(buf, seed, seedlen + 1);
|
||||||
|
for (int i = 0; i < seedlen; i++)
|
||||||
{
|
{
|
||||||
/* Substitutions */
|
for (const char *s = charset; *s; s++)
|
||||||
memcpy(buf, seed, seedlen + 1);
|
{
|
||||||
for (int i = 0; i < seedlen; i++)
|
buf[i] = *s;
|
||||||
{
|
|
||||||
for (const char *s = charset; *s; s++)
|
|
||||||
{
|
|
||||||
buf[i] = *s;
|
|
||||||
|
|
||||||
//printf("sub buf = '%s'\n", buf);
|
//printf("sub buf = '%s'\n", buf);
|
||||||
void *p;
|
void *p;
|
||||||
if (flag)
|
if (flag)
|
||||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
p = spellerY(buf, seedlen, fp, fparg, charset, i + 1);
|
||||||
else
|
else
|
||||||
p = (*fp)(fparg, buf);
|
p = (*fp)(fparg, buf);
|
||||||
if (p)
|
if (p)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
buf[i] = seed[i];
|
buf[i] = seed[i];
|
||||||
}
|
|
||||||
|
|
||||||
/* Insertions */
|
|
||||||
memcpy(buf + 1, seed, seedlen + 1);
|
|
||||||
for (int i = 0; i <= seedlen; i++)// yes, do seedlen+1 iterations
|
|
||||||
{
|
|
||||||
for (const char *s = charset; *s; s++)
|
|
||||||
{
|
|
||||||
buf[i] = *s;
|
|
||||||
|
|
||||||
//printf("ins buf = '%s'\n", buf);
|
|
||||||
void *p;
|
|
||||||
if (flag)
|
|
||||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
|
||||||
else
|
|
||||||
p = (*fp)(fparg, buf);
|
|
||||||
if (p)
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
buf[i] = seed[i];// going past end of seed[] is ok, as we hit the 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;// didn't find any corrections
|
/* Insertions */
|
||||||
|
memcpy(buf + 1, seed, seedlen + 1);
|
||||||
|
for (int i = 0; i <= seedlen; i++) // yes, do seedlen+1 iterations
|
||||||
|
{
|
||||||
|
for (const char *s = charset; *s; s++)
|
||||||
|
{
|
||||||
|
buf[i] = *s;
|
||||||
|
|
||||||
|
//printf("ins buf = '%s'\n", buf);
|
||||||
|
void *p;
|
||||||
|
if (flag)
|
||||||
|
p = spellerY(buf, seedlen + 1, fp, fparg, charset, i + 1);
|
||||||
|
else
|
||||||
|
p = (*fp)(fparg, buf);
|
||||||
|
if (p)
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
buf[i] = seed[i]; // going past end of seed[] is ok, as we hit the 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL; // didn't find any corrections
|
||||||
}
|
}
|
||||||
|
|
||||||
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset)
|
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset)
|
||||||
{
|
{
|
||||||
|
size_t seedlen = strlen(seed);
|
||||||
for (int distance = 0; distance < 2; distance++)
|
for (int distance = 0; distance < 2; distance++)
|
||||||
{ void *p = spellerX(seed, fp, fparg, charset, distance);
|
{ void *p = spellerX(seed, seedlen, fp, fparg, charset, distance);
|
||||||
if (p)
|
if (p)
|
||||||
return p;
|
return p;
|
||||||
|
// if (seedlen > 10)
|
||||||
|
// break;
|
||||||
}
|
}
|
||||||
return NULL; // didn't find it
|
return NULL; // didn't find it
|
||||||
}
|
}
|
||||||
@@ -131,6 +208,7 @@ void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charse
|
|||||||
|
|
||||||
void *speller_test(void *fparg, const char *s)
|
void *speller_test(void *fparg, const char *s)
|
||||||
{
|
{
|
||||||
|
//printf("speller_test(%s, %s)\n", fparg, s);
|
||||||
if (strcmp((char *)fparg, s) == 0)
|
if (strcmp((char *)fparg, s) == 0)
|
||||||
return fparg;
|
return fparg;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -141,18 +219,28 @@ void unittest_speller()
|
|||||||
static const char *cases[][3] =
|
static const char *cases[][3] =
|
||||||
{
|
{
|
||||||
{ "hello", "hell", "y" },
|
{ "hello", "hell", "y" },
|
||||||
{ "hello", "abcd", "n" },
|
|
||||||
{ "hello", "hel", "y" },
|
{ "hello", "hel", "y" },
|
||||||
{ "ehllo", "helol", "y" },
|
{ "hello", "ello", "y" },
|
||||||
|
{ "hello", "llo", "y" },
|
||||||
|
{ "hello", "hellox", "y" },
|
||||||
|
{ "hello", "helloxy", "y" },
|
||||||
|
{ "hello", "xhello", "y" },
|
||||||
|
{ "hello", "xyhello", "y" },
|
||||||
|
{ "hello", "ehllo", "y" },
|
||||||
|
{ "hello", "helol", "y" },
|
||||||
|
{ "hello", "abcd", "n" },
|
||||||
|
//{ "ehllo", "helol", "y" },
|
||||||
{ "hello", "helxxlo", "y" },
|
{ "hello", "helxxlo", "y" },
|
||||||
{ "hello", "ehlxxlo", "n" },
|
{ "hello", "ehlxxlo", "n" },
|
||||||
{ "hello", "heaao", "y" },
|
{ "hello", "heaao", "y" },
|
||||||
|
{ "_123456789_123456789_123456789_123456789", "_123456789_123456789_123456789_12345678", "y" },
|
||||||
};
|
};
|
||||||
//printf("unittest_speller()\n");
|
//printf("unittest_speller()\n");
|
||||||
void *p = speller("hello", &speller_test, (void *)"hell", idchars);
|
const void *p = speller("hello", &speller_test, (void *)"hell", idchars);
|
||||||
assert(p != NULL);
|
assert(p != NULL);
|
||||||
for (int i = 0; i < sizeof(cases)/sizeof(cases[0]); i++)
|
for (int i = 0; i < sizeof(cases)/sizeof(cases[0]); i++)
|
||||||
{
|
{
|
||||||
|
//printf("case [%d]\n", i);
|
||||||
void *p = speller(cases[i][0], &speller_test, (void *)cases[i][1], idchars);
|
void *p = speller(cases[i][0], &speller_test, (void *)cases[i][1], idchars);
|
||||||
if (p)
|
if (p)
|
||||||
assert(cases[i][2][0] == 'y');
|
assert(cases[i][2][0] == 'y');
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ unsigned AggregateDeclaration::size(Loc loc)
|
|||||||
//printf("AggregateDeclaration::size() = %d\n", structsize);
|
//printf("AggregateDeclaration::size() = %d\n", structsize);
|
||||||
if (!members)
|
if (!members)
|
||||||
error(loc, "unknown size");
|
error(loc, "unknown size");
|
||||||
|
if (sizeok != 1 && scope)
|
||||||
|
semantic(NULL);
|
||||||
if (sizeok != 1)
|
if (sizeok != 1)
|
||||||
{ error(loc, "no size yet for forward reference");
|
{ error(loc, "no size yet for forward reference");
|
||||||
//*(char*)0=0;
|
//*(char*)0=0;
|
||||||
@@ -181,6 +183,8 @@ void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ts->sym->sizeok != 1 && ts->sym->scope)
|
||||||
|
ts->sym->semantic(NULL);
|
||||||
if (ts->sym->sizeok != 1)
|
if (ts->sym->sizeok != 1)
|
||||||
{
|
{
|
||||||
sizeok = 2; // cannot finish; flag as forward referenced
|
sizeok = 2; // cannot finish; flag as forward referenced
|
||||||
|
|||||||
@@ -3544,7 +3544,11 @@ void TemplateInstance::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
errors = 1;
|
errors = 1;
|
||||||
if (global.gag)
|
if (global.gag)
|
||||||
|
{ // Try to reset things so we can try again later to instantiate it
|
||||||
tempdecl->instances.remove(tempdecl_instance_idx);
|
tempdecl->instances.remove(tempdecl_instance_idx);
|
||||||
|
semanticRun = 0;
|
||||||
|
inst = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LOG
|
#if LOG
|
||||||
|
|||||||
Reference in New Issue
Block a user