commit x64 compilation from lulu cause the other branch dont seems to compile properly at home

This commit is contained in:
2026-07-17 16:08:20 +02:00
parent c0f3eeb00d
commit 0efa4ee6f7
625 changed files with 117283 additions and 4426 deletions

View File

@ -0,0 +1,266 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "script_squirrel/squirrel_analyzer.h"
#include "ascii/parser.h"
#include "filesystem/filesystem.h"
#include "platform.h"
using namespace GS;
using namespace GS::SquirrelAnalyzer;
using namespace GS::AsciiParser;
//------------------------------------------------------------------------------
/* static bool SymbolFindByNameFunctor(Symbol *s, const char *n) { return s->name == n; } */
static bool SourceFindByNameFunctor(Source *s, const char *n) { return s->name == n; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
struct ParserContext
{
const char *s, *e, *o;
SharedList <Symbol *> *symbols;
Symbol::Type type;
Offset CurrentOffset() const
{
Offset offset(1, 0);
for (const char *p = o; p < e; ++offset.line)
{
const char *eol = RunToEOL(p, e);
if (eol > s)
{
offset.column = s - p;
break;
}
if (eol >= e)
return Offset(1, 0);
p = SkipEOL(eol, e);
}
return offset;
}
ParserContext(const char *_s, const char *_e, const char *_o, SharedList <Symbol *> *_symbols, Symbol::Type _type) : s(_s), e(_e), o(_o), symbols(_symbols), type(_type) {}
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void ParseContext(ParserContext &);
bool ParseMemberVariable(ParserContext &ctx)
{
AutoPtr <Variable> _var(new Variable);
_var->offset = ctx.CurrentOffset();
_var->var_type = Variable::VarMember;
const char *e = SkipEntry(ctx.s, ctx.e);
_var->name.Set(ctx.s, e);
ctx.s = NextEntry(ctx.s, ctx.e) + 1;
ctx.symbols->Add(_var.Detach());
return true;
}
bool ParseGlobalVariable(ParserContext &ctx)
{
AutoPtr <Variable> _var(new Variable);
_var->offset = ctx.CurrentOffset();
_var->var_type = Variable::VarGlobal;
const char *e = SkipEntry(ctx.s, ctx.e);
_var->name.Set(ctx.s, e);
ctx.s = NextEntry(ctx.s, ctx.e) + 2;
ctx.symbols->Add(_var.Detach());
return true;
}
bool ParseLocalVariable(ParserContext &ctx)
{
AutoPtr <Variable> _var(new Variable);
_var->offset = ctx.CurrentOffset();
_var->var_type = Variable::VarLocal;
const char *s = NextEntry(ctx.s, ctx.e);
_var->name.Set(s, SkipEntry(s, ctx.e));
ctx.symbols->Add(_var.Detach());
// parse subsequent declarations.
s = NextEntry(s, ctx.e);
forever
{
/*
// TODO a naive test won't do as there is no mandatory end-of-statement in Squirrel
if (s[0] == '=')
{
// check if there are more variables declared by this statement
}
*/
if (s[0] == ',')
{
s = NextEntry(s + 1, ctx.e);
ctx.s = s;
_var = new Variable;
_var->offset = ctx.CurrentOffset();
_var->var_type = Variable::VarLocal;
_var->name.Set(s, SkipEntry(s, ctx.e));
ctx.symbols->Add(_var.Detach());
s = NextEntry(s, ctx.e);
}
else
break;
}
ctx.s = s;
return true;
}
bool ParseFunction(ParserContext &ctx)
{
AutoPtr <Function> _function(new Function);
_function->offset = ctx.CurrentOffset();
const char *s = NextEntry(ctx.s, ctx.e);
_function->name.Set(s, SkipEntry(s, ctx.e));
s = NextEntry(s, ctx.e);
// Parse prototype.
if (s[0] != '(')
return false;
const char *eoproto = RunToEOG(s, ctx.e, '(', ')');
if (eoproto == NULL)
return false;
_function->prototype.Set(s + 1, eoproto);
s = NextEntry(eoproto + 1, ctx.e);
// Parse function content.
if (s[0] != '{')
return false;
const char *eofunc = RunToEOG(s, ctx.e, '{', '}');
if (eofunc == NULL)
eofunc = ctx.e;
ParserContext func_ctx(s + 1, eofunc, ctx.o, &_function->symbols, _function->type);
ParseContext(func_ctx);
ctx.s = eofunc + 1;
ctx.symbols->Add(_function.Detach());
return true;
}
bool ParseClass(ParserContext &ctx)
{
AutoPtr <Class> _class(new Class);
_class->offset = ctx.CurrentOffset();
ctx.s = NextEntry(ctx.s, ctx.e);
_class->name.Set(ctx.s, SkipEntry(ctx.s, ctx.e));
const char *s = NextEntry(ctx.s, ctx.e);
if (!String::strccmp("extends", s))
{
s = NextEntry(s, ctx.e);
_class->extends.Set(s, SkipEntry(s, ctx.e));
ctx.s = SkipEntry(s, ctx.e);
s = NextEntry(s, ctx.e);
if (s == ctx.e)
return false;
}
// Parse class content.
if (s[0] != '{')
return false;
const char *eoclass = RunToEOG(s, ctx.e, '{', '}');
if (eoclass == NULL)
eoclass = ctx.e;
ParserContext class_ctx(s + 1, eoclass, ctx.o, &_class->symbols, _class->type);
ParseContext(class_ctx);
ctx.s = eoclass + 1;
ctx.symbols->Add(_class.Detach());
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void ParseContext(ParserContext &ctx)
{
for (bool r = true; r && (ctx.s < ctx.e); )
{
if (!String::strccmp("class", ctx.s))
r = ParseClass(ctx);
else if (!String::strccmp("function", ctx.s))
r = ParseFunction(ctx);
else if (!String::strccmp("local", ctx.s))
r = ParseLocalVariable(ctx);
else
{
const char *e = SkipEntry(ctx.s, ctx.e);
String tmp(ctx.s, e);
const char *s = NextEntry(ctx.s, ctx.e);
if (ctx.s == s)
++ctx.s; // skip
else
{
if ((s[0] == '<') && (s[1] == '-'))
r = ParseGlobalVariable(ctx);
else if ((ctx.type == Symbol::TypeClass) && (s[0] == '='))
r = ParseMemberVariable(ctx);
else
ctx.s = s;
}
}
}
}
Source *ParseSource(const char *s, const char *e)
{
AutoPtr <Source> source(new Source);
ParserContext ctx(s, e, s, &source->symbols, Symbol::TypeNone);
ParseContext(ctx);
return source.Detach();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Source *SquirrelAnalyzer::Analyze(const char *nut, Program &program, bool replace)
{
Source *old_source = ListFindEx(program.sources, SourceFindByNameFunctor, nut);
if (old_source && !replace)
return NULL;
String source;
{
Array <char> buffer;
if (!Platform::Get().io->FileLoad(nut, buffer))
return NULL;
source.Set(buffer.c_ptr(), buffer.c_ptr() + buffer.GetCount());
}
Source *new_source = ParseSource(source.c_str(), source.c_str() + source.Len());
if (!new_source)
return NULL;
new_source->name = nut;
program.sources.Remove(old_source);
program.sources.Add(new_source);
return new_source;
}
//------------------------------------------------------------------------------