Implement with statement support. #56

This commit is contained in:
Hackerpilot 2014-09-22 00:21:23 +00:00
parent b37b4b9dab
commit d9abe32f6c
6 changed files with 71 additions and 8 deletions

@ -1 +1 @@
Subproject commit 27f45e6490e7ef0e9a6ef604e51f68a54b10ee2d
Subproject commit d57e38c169613edfa39088adb933fd220b6208f3

View File

@ -41,7 +41,7 @@ enum SymbolQualifier : ubyte
{
/// _none
none,
/// the symbol is an _array
/// the symbol is an array
array,
/// the symbol is a associative array
assocArray,
@ -61,6 +61,9 @@ public:
*/
@disable this();
/// ditto
@disable this(this);
/**
* Params:
* name = the symbol's name
@ -253,8 +256,12 @@ struct Scope
{
foreach (item; sc.symbols[])
{
if (item.kind == CompletionKind.importSymbol) foreach (i; item.type.parts[])
symbols.insert(i);
if (item.kind == CompletionKind.importSymbol
|| item.kind == CompletionKind.withSymbol)
{
foreach (i; item.type.parts[])
symbols.insert(i);
}
else
symbols.insert(item);
}
@ -276,6 +283,25 @@ struct Scope
auto er = symbols.equalRange(&s);
if (!er.empty)
return array(er);
// Check symbols from "with" statement
ACSymbol ir2 = ACSymbol(WITH_SYMBOL_NAME);
auto r2 = symbols.equalRange(&ir2);
if (!r2.empty)
{
auto app = appender!(ACSymbol*[])();
foreach (e; r2)
{
if (e.type is null)
continue;
foreach (withSymbol; e.type.parts.equalRange(&s))
app.put(withSymbol);
}
if (app.data.length > 0)
return app.data;
}
// Check imported symbols
ACSymbol ir = ACSymbol(IMPORT_SYMBOL_NAME);
auto r = symbols.equalRange(&ir);
if (!r.empty)
@ -386,6 +412,7 @@ private immutable(string[24]) builtinTypeNames;
* static construction.
*/
immutable string IMPORT_SYMBOL_NAME;
immutable string WITH_SYMBOL_NAME;
/**
* Translates the IDs for built-in types into an interned string.
@ -454,6 +481,7 @@ static this()
builtinTypeNames[23] = internString("creal");
IMPORT_SYMBOL_NAME = internString("public");
WITH_SYMBOL_NAME = internString("with");
auto bool_ = allocate!ACSymbol(Mallocator.it, "bool", CompletionKind.keyword);

View File

@ -385,9 +385,9 @@ final class FirstPass : ASTVisitor
if (blockStatement.declarationsAndStatements !is null)
{
currentScope = s;
currentScope = s;
visit (blockStatement.declarationsAndStatements);
currentScope = s.parent;
currentScope = s.parent;
}
}
@ -453,6 +453,30 @@ final class FirstPass : ASTVisitor
currentSymbol.addChild(symbol);
}
override void visit(const WithStatement withStatement)
{
if (withStatement.expression !is null
&& withStatement.statementNoCaseNoDefault !is null)
{
Scope* s = allocate!Scope(semanticAllocator,
withStatement.statementNoCaseNoDefault.startLocation,
withStatement.statementNoCaseNoDefault.endLocation);
SemanticSymbol* symbol = allocateSemanticSymbol(WITH_SYMBOL_NAME,
CompletionKind.withSymbol, symbolFile, s.startLocation, null);
symbol.acSymbol.qualifier = SymbolQualifier.withSymbol;
Log.trace("WithStatement bounds: ", s.startLocation, " ", s.endLocation);
s.parent = currentScope;
currentScope.children.insert(s);
populateInitializer(symbol, withStatement.expression, false);
symbol.parent = currentSymbol;
currentSymbol.addChild(symbol);
withStatement.accept(this);
currentScope = currentScope.parent;
}
else
withStatement.accept(this);
}
alias visit = ASTVisitor.visit;
/// Module scope

View File

@ -81,9 +81,11 @@ private:
*/
void assignToScopes(ACSymbol* currentSymbol)
{
Scope* s = moduleScope.getScopeByCursor(currentSymbol.location);
if (currentSymbol.kind != CompletionKind.moduleName)
{
Scope* s = moduleScope.getScopeByCursor(currentSymbol.location);
s.symbols.insert(currentSymbol);
}
foreach (part; currentSymbol.parts[])
{
if (part.kind != CompletionKind.keyword)

View File

@ -70,14 +70,19 @@ private:
case interfaceName:
resolveInheritance(currentSymbol);
break;
case withSymbol:
case variableName:
case memberVariableName:
case functionName:
case aliasName:
ACSymbol* t = resolveType(currentSymbol.initializer,
currentSymbol.type, currentSymbol.acSymbol.location);
while (t !is null && t.kind == CompletionKind.aliasName)
while (t !is null && (t.kind == CompletionKind.aliasName
|| (currentSymbol.acSymbol.kind == CompletionKind.withSymbol
&& t.kind == CompletionKind.variableName)))
{
t = t.type;
}
currentSymbol.acSymbol.type = t;
break;
case structName:

View File

@ -31,6 +31,10 @@ enum CompletionKind : char
/// be returned in a completion response.
importSymbol = '*',
/// With symbol. This is used internally and will never
/// be returned in a completion response.
withSymbol = 'w',
/// class names
className = 'c',